我有一个充满字典的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;
答案 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
,则应覆盖该对象上的NSSet
和NSSet
。有关详细信息,请参阅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。