ios 检查数组是否包含另一个数组的相同对象的最快方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14935233/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fastest way to check if an array contains the same objects of another array
提问by FrankZp
The goal is to compare two arrays as and check if they contain the same objects (as fast as possible - there are lots of objects in the arrays). The arrays cannot be checked with isEqual:
as they are differently sorted.
目标是比较两个数组并检查它们是否包含相同的对象(尽可能快 - 数组中有很多对象)。无法检查数组,isEqual:
因为它们的排序方式不同。
I already tried the solution posted here (https://stackoverflow.com/a/1138417- see last code snippet of the post by Peter Hosey). But this doesn't work with differently sorted arrays.
我已经尝试过这里发布的解决方案(https://stackoverflow.com/a/1138417- 请参阅 Peter Hosey 帖子的最后一段代码)。但这不适用于不同排序的数组。
The code I'm using now is the following:
我现在使用的代码如下:
+ (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;
}
This works, but those are two nested fast enumerations. Is there a way to do a faster comparison?
这是有效的,但这是两个嵌套的快速枚举。有没有办法进行更快的比较?
回答by Anoop Vaidya
As per your code, you are strict to same number of elements and each object of first array should be there in second array and vice versa.
根据您的代码,您严格限制相同数量的元素,并且第一个数组的每个对象都应该在第二个数组中,反之亦然。
The fastest way would be to sort both the array and compare them.
最快的方法是对数组进行排序并进行比较。
Ex:
前任:
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");
}
回答by Shashank
How about converting both arrays to sets and comparing them.
如何将两个数组转换为集合并比较它们。
NSSet *set1 = [NSSet setWithArray:arr1];
NSSet *set2 = [NSSet setWithArray:arr2];
Compare the two using
比较两者使用
if([set1 isEqualToSet:set2]) {
}
回答by Pushpak Narasimhan
Use containsObject: method instead of iterating the whole array.
使用 containsObject: 方法而不是迭代整个数组。
NSArray *array;
array = [NSArray arrayWithObjects: @"Nicola", @"Margherita", @"Luciano", @"Silvia", nil];
if ([array containsObject: @"Nicola"]) // YES
{
// Do something
}
like this
像这样
+ (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;
}
回答by simon_smiley
Tried to get the accepted answer working but it wasn't quite the best fit for my situation.
试图让接受的答案起作用,但它并不是最适合我的情况。
I found this answerand all credit goes to @joel kravets for the method.
我找到了这个答案,并且该方法的所有功劳都归功于@joel kravets。
Basically sorting using a comparator enables you to sort using objects more easily - hence the problem I was facing when trying to use the above solution.
基本上使用比较器进行排序使您可以更轻松地使用对象进行排序 - 因此我在尝试使用上述解决方案时面临的问题。
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");
}
Previously I had tried to use other answers like those above, using break to go through loops but in the end this answer came out easiest probably due to its speed and also that in the end we have the if statement allowing us to put code depending on if they are the same or different.
以前我曾尝试使用上述其他答案,使用 break 来遍历循环,但最终这个答案最简单,可能是由于它的速度,而且最后我们有 if 语句允许我们根据以下条件放置代码如果它们相同或不同。
Thanks to Anoop for getting me on the right track and Joel for helping me to tighten the efficiency of it
感谢 Anoop 让我走上正轨,感谢 Joel 帮助我提高效率
回答by gnasher729
If you want to check whether both arrays contain the same duplicates, just use NSCountedSet. It's like an NSSet, but each object in the set also has a count telling you how often it has been added. So
如果要检查两个数组是否包含相同的重复项,只需使用 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]);
}
No matter how you do it, this will be time consuming, so you might consider if there are special cases that can be handled quicker. Are these arrays usually the same, or almost the same, or is it true 99% of the time that they are different and that 99% of the time a random element of array1 is not in array2? Are the arrays often sorted? In that case, you could check whether there are identical objects in identical positions, and then consider only those objects that are not the same. If one array contains objects a, b, c, d, e and the other contains a, b, x, d, y, then you only need to compare the array [c, e] vs. [x, y].
不管你怎么做,这都会很耗时,所以你可以考虑是否有特殊情况可以更快处理。这些数组通常是相同的还是几乎相同的,或者它们在 99% 的情况下是不同的,而 array1 的随机元素在 99% 的情况下不在 array2 中?数组是否经常排序?在这种情况下,您可以检查是否有相同位置的相同对象,然后只考虑那些不相同的对象。如果一个数组包含对象 a, b, c, d, e 而另一个包含 a, b, x, d, y,那么您只需要比较数组 [c, e] 与 [x, y]。
回答by Ramy Al Zuhouri
This way the complexity is O(N^2), if you follow this approach you can't do it with a lower complexity. While instead you can do it with O(N log(N)) if you sort both arrays and then compare them. This way after having them sorted you will do it using isEqualToArray: in other N operations.
这种方式的复杂度是 O(N^2),如果你遵循这种方法,你就不能以较低的复杂度来做到这一点。相反,如果您对两个数组进行排序然后比较它们,则可以使用 O(N log(N)) 来完成。这样在对它们进行排序后,您将使用 isEqualToArray: 在其他 N 个操作中进行。
回答by iiFreeman
NSArray *filtered = [someArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"someParamter == %@", paramValue]]];
if (filtered.count) {
}
the main plus is you can use it for any kind of objects: custom, system, NSDictionary. for example I need to know is my UINavigationController's stack contains MySearchResultsVC and MyTopMenuItemsVC or not:
主要优点是您可以将它用于任何类型的对象:自定义、系统、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! */
}
回答by Madhu
[docTypes containsObject:@"Object"];
It will works for your req. As early as fast it will return boolean value for it.
它将适用于您的要求。尽快它会为它返回布尔值。
回答by 0yeoj
I know it's late but i just wanna share what i did..
我知道已经晚了,但我只想分享我所做的..
NSString *stringArr1 = [NSString stringWithFormat:@"%@", array1];
NSString *stringArr2 = [NSString stringWithFormat:@"%@", array2];
if ([stringArr1 isEqual: stringArr2])
NSLog(@"identical");
else
NSLog(@"not");
this is just like comparing "@[@1,@2,@3,@4]" == "[@3,@2,@1,@4]".. which is obviously false..
这就像比较"@[@1,@2,@3,@4]" == "[@3,@2,@1,@4]".. 这显然是错误的..
回答by spider1983
i guess this will do:
我想这会做:
[array1 isEqualToArray:array2];
returns bool;
返回布尔值;