如何从NSArray中有效地提取匹配的对象?

时间:2013-10-14 10:17:10

标签: ios objective-c performance sorting search

我正在寻找实现以下任务的最有效方法......

我有一个Foo类型的对象数组,除其他属性外,Foo还有latitudelongitude属性。给定一个包含许多Foo的数组,我需要将匹配lat / long的Foo提取到一个新数组中。

我已经实现了几个正在运行的解决方案,包括使用for循环进行迭代,以及使用NSPredicate的解决方案,但这两种方法都涉及通过数组进行多次迭代。这个数组可能有数十万条记录,所以我正在寻找一些可以在一次通过中实现预期结果的东西。

编辑:添加一些伪代码来描述我已采取的方法并更好地描述问题......

NSMutableArray * matchingLocations = [[NSMutableArray alloc] initWithCapacity:0];

for (Foo * checkingFoo in fooArray) {

    NSMutableArray * checkingArray = [NSArray arrayWithArray:fooArray];
    [checkingArray removeObject:checkingFoo];        

    for (Foo * foo  in checkingArray) {

        // I have a method coded for comparing two coordinates
        if (checkingFoo.coordinate == foo.coordinate) { 

            [matchingLocations addObject:checkingFoo];                

        }

    }

}

3 个答案:

答案 0 :(得分:1)

NSSet将提供一组唯一对象。为了正确实现它,您需要定义Foo对象的相同含义。你可以在你的Foo类实现中重写方法isEqual:和方法hash 在你的Foo课程中:

- (BOOL)isEqual:(id)object {
return (self.coordinate == [(Foo *)object coordinate]);

}

- (NSUInteger)hash {
return ([self.coordinate hash]);

}

然后您的代码中的任何地方都可以使用:

    NSArray *array; // Your array with multiple Foo objects potentiually duplicates
NSSet *set = [NSSet setWithArray:array];

为Apple文档参考提供一个loo kat:
[NSObject isEqual:] https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/isEqual

[NSSet setWithArray:] https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSSet_Class/Reference/Reference.html#//apple_ref/occ/clm/NSSet/setWithArray

答案 1 :(得分:0)

对于相同数组的循环,您正在运行两个快速枚举。哪个不对。如果你想比较坐标,那么执行不同数组的循环。而且,如果只是你正在使用的循环,你也可以直接添加到可变数组。

答案 2 :(得分:0)

如果你想比较数组中的对象,那么我建议你使用NSSet代替NSArray。

它非常易于使用,下面的链接是您想要的,因为我使用NSMutableSet解决了这种情况:

NSSet Tutorial