最快的方法来检查一个数组是否包含另一个数组的相同对象

目标是比较两个数组,并检查它们是否包含相同的对象(尽可能快 – 数组中有很多对象)。 数组不能用isEqual:检查isEqual:因为它们是不同的sorting方式。

我已经尝试过这里发布的解决scheme( https://stackoverflow.com/a/1138417 – 请参阅Peter Hosey的post的最后一段代码片段)。 但是这不适用于不同的sorting数组。

我现在使用的代码如下:

 + (BOOL)arraysContainSameObjects:(NSArray *)array1 andOtherArray:(NSArray *)array2 { // quit if array count is different if ([array1 count] != [array2 count]) return NO; BOOL bothArraysContainTheSameObjects = YES; for (id objectInArray1 in array1) { BOOL objectFoundInArray2 = NO; for (id objectInArray2 in array2) { if ([objectInArray1 isEqual:objectInArray2]) { objectFoundInArray2 = YES; break; } } if (!objectFoundInArray2) { bothArraysContainTheSameObjects = NO; break; } } return bothArraysContainTheSameObjects; } 

这工作,但这是两个嵌套快速枚举。 有没有办法做一个更快的比较?

根据你的代码,你对同样数量的元素是严格的,第一个数组的每个对象应该在第二个数组中,反之亦然。

最快的方法是对这两个数组进行sorting并进行比较。

例如:

 NSArray *array1=@[@"a",@"b",@"c"]; NSArray *array2=@[@"c",@"b",@"a"]; array1=[array1 sortedArrayUsingSelector:@selector(compare:)]; array2=[array2 sortedArrayUsingSelector:@selector(compare:)]; if ([array1 isEqualToArray:array2]) { NSLog(@"both have same elements"); } else{ NSLog(@"both having different elements"); } 

如何转换这两个数组设置和比较它们。

 NSSet *set1 = [NSSet setWithArray:arr1]; NSSet *set2 = [NSSet setWithArray:arr2]; 

比较两者使用

 if([set1 isEqualToSet:set2]) { } 

使用containsObject:方法而不是迭代整个数组。

 NSArray *array; array = [NSArray arrayWithObjects: @"Nicola", @"Margherita", @"Luciano", @"Silvia", nil]; if ([array containsObject: @"Nicola"]) // YES { // Do something } 

喜欢这个

 + (BOOL)arraysContainSameObjects:(NSArray *)array1 andOtherArray:(NSArray *)array2 { // quit if array count is different if ([array1 count] != [array2 count]) return NO; BOOL bothArraysContainTheSameObjects = YES; for (id objectInArray1 in array1) { if (![array2 containsObject:objectInArray1]) { bothArraysContainTheSameObjects = NO; break; } } return bothArraysContainTheSameObjects; } 

如果你想检查两个数组是否包含相同的重复项,只需使用NSCountedSet。 它就像一个NSSet,但是这个集合中的每个对象都有一个计数,告诉你它多久添加一次。 所以

 BOOL same = (array1.count == array2.count); if (same && array.count > 0) { NSCountedSet* set1 = [[NSCountedSet alloc] initWithArray:array1]; NSCountedSet* set2 = [[NSCountedSet alloc] initWithArray:array2]; same = ([set1 isEqual: set2]); } 

不pipe你怎么做,这将是非常耗时的,所以你可以考虑是否有特殊情况可以更快地处理。 这些数组通常是相同的,或者几乎相同,或者99%的时间是不同的,99%的时间是array1的随机元素不在array2中? 数组是否经常被sorting? 在这种情况下,可以检查相同位置是否有相同的对象,然后只考虑那些不相同的对象。 如果一个数组包含对象a,b,c,d,e,另一个包含a,b,x,d,y,则只需要比较数组[c,e]和[x,y]。

试图让接受的答案工作,但它不是最适合我的情况。

我find了这个答案 ,所有的功劳都归功于@joel kravets的方法。

基本上使用比较器sorting使您可以更容易地使用对象进行sorting – 因此,我尝试使用上述解决scheme时遇到的问题。

 NSArray * array1 = [NSArray arrayWithArray:users]; NSArray * array2 = [NSArray arrayWithArray:threadUsers]; id mySort = ^(BUser * user1, BUser * user2){ return [user1.name compare:user2.name]; }; array1 = [array1 sortedArrayUsingComparator:mySort]; array2 = [array2 sortedArrayUsingComparator:mySort]; if ([array1 isEqualToArray:array2]) { NSLog(@"both are same"); } else{ NSLog(@"both are different"); } 

以前我曾尝试使用上面的其他答案,使用break来循环,但最终这个答案是最简单的,可能是由于它的速度,最后我们有if语句,允许我们把代码依赖于如果他们是相同或不同的。

感谢Anoop让我走上正轨,Joel帮助我收紧效率

 [docTypes containsObject:@"Object"]; 

它会适合你的需求。 早到它将返回布尔值。

这样的复杂性是O(N ^ 2),如果你遵循这种方法,你不能以较低的复杂性来做到这一点。 而如果对两个数组进行sorting然后进行比较,则可以用O(N log(N))来完成。 将它们sorting后,这样做将使用isEqualToArray:在其他N个操作中执行。

 NSArray *filtered = [someArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"someParamter == %@", paramValue]]]; if (filtered.count) { } 

主要的好处是你可以使用它的任何types的对象:自定义,系统,NSDictionary。 例如我需要知道的是我的UINavigationController的堆栈包含MySearchResultsVC和MyTopMenuItemsVC或不:

  NSArray *filtered = [self.navigationController.viewControllers filteredArrayUsingPredicate: [NSPredicate predicateWithFormat:@"class IN %@", [NSArray arrayWithObjects: [MySearchResultsVC class], [MyTopMenuItemsVC class], nil]]]; if (filtered) { /* ok, now we can handle it! */ } 

我知道这是晚了,但我只想分享我做了什么..

 NSString *stringArr1 = [NSString stringWithFormat:@"%@", array1]; NSString *stringArr2 = [NSString stringWithFormat:@"%@", array2]; if ([stringArr1 isEqual: stringArr2]) NSLog(@"identical"); else NSLog(@"not"); 

这就像比较“@ [@ 1,@ 2,@ 3,@ 4]”==“[@ 3,@ 2,@ 1,@ 4]” ,这显然是错误的..

我想这会做:

 [array1 isEqualToArray:array2]; 

返回bool;