在没有无意中杀死性能的情况下,乍一看这对于一个列表中的200个guid字符串是否可以接受,与另一个列表中的100个guid字符串相等以找到匹配的索引。
我有一个像这样定义的方法签名......
-(NSArray*)getItemsWithGuids:(NSArray*)guids
我想在guids
数组中传递,并将其与此数组一起使用...
NSArray *allPossibleItems; // Has objects with a property named guid.
...获取allPossibleItems
中具有匹配guid guids
我的第一直觉是尝试indexesOfObjectsPassingTest
但是在整理了这个块之后,我想知道iOS框架是否已经提供了更有效地进行这种比较的东西。
-(NSArray*)getItemsWithGuids:(NSArray*)guids
{
NSIndexSet *guidIndexes = [allPossibleItems indexesOfObjectsPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop)
{
SomeObjWithGuidProperty *someObject = obj;
for (NSString *guid in guids) {
if ([someObject.guid isEqualToString:guid]) {
return YES;
}
}
return NO;
}];
if (guidIndexes) {
// Have more fun here.
}
}
答案 0 :(得分:2)
由于您正在使用Objective-C(而不是Swift),请查看YoloKit。在您的情况下,您可以执行以下操作:
guids.find(^(NSString *guid){
return [someObject.guid isEqualToString:guid];
});
答案 1 :(得分:1)
我的想法是使用一套 -
-(NSArray*)getItemsWithGuids:(NSArray*)guids inAllObjects:(NSArray *)allObjects
{
NSSet *matchGuids=[NSSet setWithArray:guids];
NSMutableArray *matchingObjects=[NSMutableArray new];
for (SOmeObjectWithGuidProperty *someObject in allObjects) {
if ([matchGuids contains:someObject.guid]) {
[matchingObjects addObject:someObject];
}
}
return [matchingObjects copy];
}
答案 2 :(得分:1)
您的代码看起来会有O(n ^ 2)性能,这很糟糕。我认为将guids转换为NSSet
然后使用NSSet
的{{1}}的解决方案可能会更高效。您可以重写containsObject
代码,以便轻松使用indexesOfObjectsPassingTest
和NSSet
。
答案 3 :(得分:1)
如果订单无关紧要,我建议在这里更改数据结构。不要使用NSArray
,而是考虑使用NSDictionary
作为键guid
作为键someObject
作为值-[NSDictionary objectsForKeys:notFoundMarker:]
。在这种情况下,您应该使用NSDictionary
方法来获取对象。
它比2个数组的枚举工作速度快得多。如果NSString
键具有良好的散列函数,则访问元素,设置元素和删除元素都需要恒定的时间。 -(NSArray*)getItemsWithGuids:(NSArray*)guids {
NSArray *objectsAndNulls = [allPossibleItemsDictionary objectsForKeys:guids notFoundMarker:[NSNull null]];
if (objectsAndNulls) {
// Have more fun here.
// You should check that object in objectsAndNulls is not NSNull before using it
}
return objectsAndNulls;
}
有很好的哈希值。
nil
UPD 很遗憾,无法将NSMutableArray
作为notFoundMarker传递。如果您无法提供可用的notFoundMarker值并且不想执行其他检查,则可以逐个查询对象并填充NSNull
。在这种情况下,您将避免传递槽数组以删除-(NSArray*)getItemsWithGuids:(NSArray*)guids {
NSMutableArray *objects = [NSMutableArray arrayWithCapacity:guids.count];
for (NSString *guid in guids) {
SomeObjWithGuidProperty *object = allPossibleItemsDictionary[guid];
if (nil != object) {
[objects addObject:object];
}
}
if (nil != objects) {
// Have more fun here.
}
return object;
}
s:
ArraySum