2011-09-26 87 views
1

我正在循环访问数组,并将此数组中的对象标记属性与另一个数组中的对象进行比较。这个2x快速枚举的更好的解决方案?

这里是我的代码:

NSArray *objectsArray = ...; 
NSArray *anotherObjectArray = ...; 
NSMutableArray *mutableArray = ...; 

for (ObjectA *objectA in objectsArray) { 
    for (ObjectZ *objectZ in anotherObjectArray) { 
     if ([objectA.tag isEqualToString:objectZ.tag]) { 
      [mutableArray addObject:objectA]; 
     } 
    } 
} 

有没有更好的方式来做到这一点?

请注意tag属性不是整数,所以必须比较字符串。

+3

对不起,但如果正在使用对象A? – mackworth

+1

或者类似的,'childParent'是什么? –

+0

哦,还有一个:你为什么要优化?这段代码是否被执行了很多,或者objectsArray或[childParent children]或者两者都有很多元素? – mackworth

回答

5

您可以通过遍历每个阵列一次,而不是嵌套做到这一点:

NSMutableSet *tagSet = [NSMutableSet setWithCapacity:[anotherObjectArray count]]; 

for(ObjectZ *objectZ in antherObjectArray) { 
    [tagSet addObject:objectZ.tag]; 
} 

NSMutableArray *output = [NSMutableArray mutableArray]; 

for(ObjectA *objectA in objectsArray) { 
    if([tagSet containsObject:objectA.tag]) { 
     [output addObject:objectA]; 
    } 
} 
+0

但是,不包含对象(和indexOfObject)只是内部遍历整个集合或数组呢? – mackworth

+0

indexOfObject必须遍历数组,但containsObject是常量时间。 –

+0

伙计,你真棒。这将我的解析时间减少了50%(显然这是一个重要的循环)。非常聪明! – runmad

1

好,最简单的变化(如只能有每个对象A一场比赛),那么你可以以后做一个打破你的[mutableArray addObject:objectA]。当匹配发生时,这会将内部循环减少50%。

更为显着的是,如果你这样做了很多,并且anotherObjectArray的顺序并不重要,那就是颠倒你的anotherObjectArray数据结构并使用字典,通过标记存储对象。然后,您只需遍历objectA,询问它的标记是否在ObjectZs的字典中。

1

也许你可以使用[NSArray filteredArrayUsingPredicate:]; - http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html

但是,您可能必须自己调整属性标记。

NSArray *objectsArray = [NSArray arrayWithObjects:@"Miguel", @"Ben", @"Adam", @"Melissa", nil]; 
NSArray *tagsArray = [NSArray arrayWithObjects:@"Miguel", @"Adam", nil]; 

NSPredicate *sPredicate = [NSPredicate predicateWithFormat:@"SELF IN %@", tagsArray]; 
NSArray *results = [objectsArray filteredArrayUsingPredicate:sPredicate]; 
NSLog(@"Matched %d", [results count]); 
for (id a in results) { 
    NSLog(@"Object is %@", a); 
} 

希望这有助于

0

感谢所有的答案。虽然我已经接受了的NSMutableSet的解决方案,其实我结束了与下面去,因为它变成了它是一点点更快:

NSMutableDictionary *tagDictionary = [NSMutableDictionary dictionaryWithCapacity:[anotherObjectArray count]]; 
for (ObjectZ *objectZ in anotherObjectArray) { 
    [tagDictionary setObject:objectZ.tag forKey:objectZ.tag]; 
    } 
for (ObjectA *objectA in objectsArray) { 
    if ([tagDictionary objectForKey:objectA.tag]) { 
     [direction addObject:objectA]; 
    } 
}