Fastest way to check if an array contains the same objects of another array

FrankZp picture FrankZp · Feb 18, 2013 · Viewed 34.7k times · Source

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.

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.

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?

Answer

Anoop Vaidya picture Anoop Vaidya · Feb 18, 2013

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");
}