高效的方法是枚举一个数组,查找另一个数组中的项目

时间:2016-03-14 23:46:06

标签: ios objective-c arrays

在没有无意中杀死性能的情况下,乍一看这对于一个列表中的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.
    }
}

4 个答案:

答案 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代码,以便轻松使用indexesOfObjectsPassingTestNSSet

答案 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