0

我有一个NSArray对象Store。每个Store对象有两个NSString对象;StoreIDName。我想快速检查对象中是否存在NSArrayID Store

例子:

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

4 回答 4

4

事情是这样的:无论你采用什么解决方案,它或多或少都会归结为“遍历数组并返回是否找到对象”。除非满足非常具体的条件(例如,数组已经按您正在搜索的值排序),否则没有办法比这更快地搜索数组。您可以使用谓词,可以使用枚举器,可以使用快速枚举,也可以使用测试块——在后台,它们都相当于“遍历数组并执行测试”。这就是数组的工作方式。

如果这是您需要经常做的事情,并且性能是幼稚解决方案的问题,那么明智的解决方案可能是将您的 ID 缓存在 NSSet 中。集合已针对快速成员检测进行了调整,因此您应该能够比使用数组更快地获得答案。

我个人的“loop-over-the-array”解决方案:

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

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

于 2012-12-06T18:34:30.757 回答
2

试试这个:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@",@"id", myID];
NSArray *filteredArray = [array filteredArrayUsingPredicate:predicate];
if (filteredArray.count > 0)
  Store *store = [filteredArray objectAtIndex:0];
于 2012-12-06T16:58:10.597 回答
1

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

NSArray *results = [array valueForKey:@"id"];
BOOL myIdOneExists = [results containsObject:myIdOne];
BOOL myIdTwoExists = [results containsObject:myIdTwo];
于 2012-12-06T17:02:28.857 回答
1
-(BOOL) id:(NSString*) theId existsInArray:(NSArray*) theArray {
    for (Store* theStore in theArray) {
        if ([theStore.id isEqualToString theId]) {
            return YES;
        }
    }
    return NO;
}

另一种方法是实现仅比较 ID的isEqual方法。Store然后使用您要查找的 ID 构造一个虚拟Store对象并使用indexOfObjector containsObject,引用您的虚拟Store对象。

于 2012-12-06T17:06:43.483 回答