如何根据不同数组中包含的字符串在NSArray中查找匹配的字典

时间:2013-11-05 09:26:22

标签: objective-c arrays dictionary nsarray nsdictionary

我有一个充满字典的NSArray。

我想遍历它并查找所有字典,其键值与单独数组中存在的任何字符串对象相匹配。

然后我想将它添加到找到的所有对象的新结果数组中。

这就是我现在的做法,但我想知道是否有更有效,更快捷的方法。

NSArray *arrayOfDictionaries, *arrayOfIDs;

NSMutableArray *results = [NSMutableArray array];

for (NSDictionary *dict in arrayOfDictionaries) {

    for (NSString *userID in arrayOfIDs) {

        if ([userID isEqualToString:dict[@"user_id"]]) {

            [results addObject:dict];

        }
    }
}

return results;

2 个答案:

答案 0 :(得分:2)

是的,使用NSArray containsObject:方法,您的代码可能会更简单一些:

NSArray *arrayOfDictionaries, *arrayOfIDs;

NSMutableArray *results = [NSMutableArray array];

for (NSDictionary *dict in arrayOfDictionaries) {

    if ([arrayOfIDs containsObject:dict[@"user_id"]) {

        [results addObject:dict];

    }
}

return results;

请注意,尽管此代码更易于阅读和理解,但它仍然与原始方法类似run-time complexity

这是因为虽然您发布的代码在中间具有明确的N^2运行时复杂性(嵌套for循环),但我的新版本显然只有N复杂度,{{1调用包含一个循环,因此仍有containsObject:复杂度。

如果您希望自己的算法效率更高 - ,只有这一点很重要,不要过早优化! - 您可以使用N^2代替{{1用于存储NSSet。这会更快,因为NSArray查找是线性时间,而usersIDs使用散列进行查找,并且优于线性运行时查找。

请注意,如果您想将自己的自定义对象放入NSArray,则应覆盖该对象上的NSSetNSSet。有关详细信息,请参阅Best practices for overriding isEqual: and hash

答案 1 :(得分:1)

您可以更进一步过滤初始NSArray并获取一组索引。

NSIndexSet *results = [NSIndexSet indexSet];    

results = [arrayOfDictionaries indexesOfObjectsPassingTest:^BOOL(NSDictionary* obj, NSUInteger idx, BOOL *stop) {
    return [arrayOfIDs containsObject:obj[@"user_id"]];
}];

请注意,如果您使用containsObject代替NSSet而不是arrayOfIDs,则可以改善NSArray

如果您想要更多选项来过滤数组,请检查此stackoverflow thread