检查NSArray中的自定义对象中是否存在NSString

时间:2012-12-06 16:50:58

标签: objective-c ios nsarray

我有NSArrayStore个对象。每个Store对象都有两个NSString个对象; StoreIDName。 我想快速检查此NSArray中是否存在包含Store个对象的ID。

示例:

Store *s1 = [[Store alloc] init];
s1.name = @"Some Name";
s1.id = @"123ABC";

Store *s2 = [[Store alloc] init];
s2.name = @"Some Other Name";
s2.id = @"ABC123";

NSArray *array = [[NSArray alloc] initWithObjects:s1, s2, nil];

NSString *myIdOne = @"ABCDEF";
NSString *myIdTwo = @"123ABC";

BOOL myIdOneExists = ...?
BOOL myIdTwoExists = ...?

我需要弄清...?。我知道我可以使用for循环执行此操作并在找到时中断...但这似乎是一种令人讨厌的方法,因为NSArray可能包含数千个对象,...理论上。
所以我想知道一个更好的解决方案。

4 个答案:

答案 0 :(得分:4)

这就是事情:无论你使用什么解决方案,它都会或多或少地归结为“遍历数组并返回是否找到了对象。”除非满足非常特定的条件(例如,数组已按您正在搜索的值排序),否则无法比此更快地搜索数组。您可以使用谓词,可以使用枚举器,可以使用快速枚举,也可以使用测试块 - 在引擎盖下,它们都可以“循环遍历数组并执行测试”。这就是数组的工作原理。

如果这是您经常需要做的事情并且性能是天真解决方案的问题,一个明智的解决方案可能是将您的ID缓存在NSSet中。集合被调整为快速成员检测,因此您应该能够比使用数组更快地得到答案。

我个人的“循环阵列”解决方案:

BOOL idExists = NSNotFound != [stores indexOfObjectPassingTest:^(Store *store, NSUInteger idx, BOOL *stop) {
    return [store.id isEqualToString:@"whatever"];
}];

(写在浏览器中,所以,你知道,警告compilor。)

答案 1 :(得分:2)

试试这个:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@",@"id", myID];
NSArray *filteredArray = [array filteredArrayUsingPredicate:predicate];
if (filteredArray.count > 0)
  Store *store = [filteredArray objectAtIndex:0];

答案 2 :(得分:1)

最简单的解决方案,只需使用KVC:

NSArray *results = [array valueForKey:@"id"];
BOOL myIdOneExists = [results containsObject:myIdOne];
BOOL myIdTwoExists = [results containsObject:myIdTwo];

答案 3 :(得分:1)

-(BOOL) id:(NSString*) theId existsInArray:(NSArray*) theArray {
    for (Store* theStore in theArray) {
        if ([theStore.id isEqualToString theId]) {
            return YES;
        }
    }
    return NO;
}

另一种方法是在isEqual中实施Store方法,仅比较ID。然后使用您要查找的ID构建一个虚拟Store对象,并使用indexOfObjectcontainsObject,引用您的虚拟Store对象。