如何使用字符串值在NSArray中获取对象的索引?

22

我想要获取NSMutableArray中类别对象的索引。

类别对象拥有一个名为“category_title”的属性,我希望能够通过传递category_title的值来获取其索引。

我查看了文档,但没有找到简单的方法来实现这一目标。

3个回答

59

NSArray 不能保证您只能存储给定对象的一个副本,因此您需要确保自己处理(或使用 NSOrderedSet)。

话虽如此,这里有几种方法。如果您的类别对象实现 isEqual: 来匹配类别标题,那么您可以使用 -indexOfObject:

如果您无法这样做(因为类别对象使用不同的相等性定义),请使用 -indexOfObjectPassingTest:。它接受一个块,在其中可以执行任何测试来定义您的“测试”——在这种情况下,测试category_title字符串是否相等。

请注意,这些都是针对 NSArray 声明的,因此如果您只查看 NSMutableArray 的头文件/文档,则看不到它们。

编辑:代码示例。假设存在一个 CASCategory 类的对象,其具有 NSString 属性 categoryTitle(我无法让自己在 ivar 名称中加入下划线 :-):

    CASCategory *cat1 = [[CASCategory alloc] init];
    [cat1 setCategoryTitle:@"foo"];
    CASCategory *cat2 = [[CASCategory alloc] init];
    [cat2 setCategoryTitle:@"bar"];
    CASCategory *cat3 = [[CASCategory alloc] init];
    [cat3 setCategoryTitle:@"baz"];

    NSMutableArray *array = [NSMutableArray arrayWithObjects:cat1, cat2, cat3, nil];
    [cat1 release];
    [cat2 release];
    [cat3 release];

    NSUInteger barIndex = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        if ([[(CASCategory *)obj categoryTitle] isEqualToString:@"bar"]) {
            *stop = YES;
            return YES;
        }
        return NO;
    }];

    if (barIndex != NSNotFound) {
        NSLog(@"The title of category at index %lu is %@", barIndex, [[array objectAtIndex:barIndex] categoryTitle]);
    }
    else {
        NSLog(@"Not found");
    }

谢谢。你能发一段如何使用indexOfObjectPassingTest的代码片段吗? - jroyce
好的,非常感谢,完全满足了我的要求。 - jroyce
1
请注意,如果数组恰好为nil,则此测试将通过零索引。 - n_b
1
注意:实际上不需要设置 *stop = YES; 因为如果返回 YES,则会自动停止进一步处理数组。如 https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/#//apple_ref/occ/instm/NSArray/indexOfObjectPassingTest: 所述,“该块返回一个布尔值,指示 obj 是否通过了测试。返回 YES 将停止数组的进一步处理。” - Markus

2

我不确定我理解这个问题,但是类似这样的代码可能会起作用(假设可变数组包含“Category”类的对象):

int indx;
bool chk;
for (Category *aCategory in theArray) 
{
    chk = ([[aCategory category_title] isEqualToString:@"valOfCategoryTitle"])
    if ( chk )
        indx = [theArray indexOfObject:aCategory];
}

原则上非常正确(如果您需要支持iOS < 4,则可能是要做的事情),但对于更现代的系统,您应该考虑基于块的方法。 - Conrad Shultz
是的,块很好,但只是为了简单地说明这个想法。 - Bruce Dean
谢谢。看到这个答案和Conrad Shultz的基于块的答案都很有启发性。 - Basil Bourque

-1
尝试使用这个更简单的代码:-
int f = [yourArray indexOfObject:@"yourString"];

2
OP想要搜索自定义对象的数组,而不是字符串数组。 - Conrad Shultz
你也可以这样搜索一个对象,我已经为字符串和对象实现了这个功能。 - Leena
2
当然可以,但这要求自定义类的-isEqual:方法针对OP的情况,进行一个字符串相等性检查,即category_title。由于问题中没有表明这一点,因此按照现有的写法,这个解决方案通常不会起作用。 - Conrad Shultz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接