Reputation: 1759
I have two NSArray
s where the objects of the arrays are the same but might be in different indices. It should print both are equal irrespective of their indices.
NSArray *arr1 = [[NSArray alloc]initWithObjects:@"aa", @"bb", @"1", @"cc", nil];
NSArray *arr2 = [[NSArray alloc]initWithObjects:@"bb", @"cc", @"1", @"aa", nil];
if ([arr1 isEqualToArray:arr2])
{
NSLog(@"Equal");
}
else
{
NSLog(@"Not equal");
}
The above code is printing 'Not equal'
but it should print 'Equal'
. How can I do this?
Upvotes: 17
Views: 24293
Reputation: 1645
Another option is to convert the NSArrays to JSON strings, and compare using isEqualToString.
-(BOOL)isArray:(NSArray *)firstArray equalContentsToArray:(NSArray *)secondArray {
if (!firstArray) {
firstArray=@[];
}
if (!secondArray) {
secondArray=@[];
}
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:firstArray options:0 error:&error];
NSString *jsonStringOne = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
jsonData = [NSJSONSerialization dataWithJSONObject:secondArray options:0 error:&error];
NSString *jsonStringTwo = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
BOOL isEqual=NO;
if ([jsonStringOne isEqualToString:jsonStringTwo]) {
isEqual=YES;
}
return isEqual;
}
I'd be curious as to a performance comparison of all these methods.
Upvotes: -2
Reputation: 1077
Most of the answers here actually do not work for fairly common cases (see their comments). There is a very good data structure that will solve this problem: NSCountedSet.
The counted set is unordered, but does care about the number of items present, so you don't end up with @[1, @1, @2] == @[@1, @2, @2]
.
NSArray *array1 = @[@1, @1, @2];
NSArray *array2 = @[@1, @2, @2];
NSCountedSet *set1 = [[NSCountedSet alloc] initWithArray:array1];
NSCountedSet *set2 = [[NSCountedSet alloc] initWithArray:array2];
BOOL isEqual = [set1 isEqualToSet:set2];
NSLog(@"isEqual:%d", isEqual);
Upvotes: 21
Reputation: 64
This can be done by using one NSMutableArray.The main point to be remembered is that the larger array should be saved in NSMutableArray. Otherwise it wont work as expected. The code is given below.
NSArray *array1 = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
NSArray *array2 = [NSArray arrayWithObjects:@"Two", @"Three", @"One", nil];
NSMutableArray *intermediate = [NSMutableArray arrayWithArray:array1];
[intermediate removeObjectsInArray:array2];
NSUInteger difference = [intermediate count];//returns the number of difference between two arrays.
Upvotes: 1
Reputation: 73608
Try this. What I am doing is make a copy of your first array & remove copy elements from the second array. If its empty then its equal, else not equal.
This has lesser memory foot print than @rmaddy solution. You create a duplicate of only one array not both arrays...
NSMutableArray *copyArray;
if([arr1 count] >= [arr2 count])
{
copyArray = [NSMutableArray arrayWithArray:arr1];
[copyArray removeObjectsInArray:arr2];
}
else //c(arr2) > c(arr1)
{
copyArray = [NSMutableArray arrayWithArray:arr2];
[copyArray removeObjectsInArray:arr1];
}
if([copyArray count] != 0)
NSLog('Not Equal');
else
NSLog('Equal');
UPDATE1: If you want to use arr2
after this then its been changed. You need to make a copy of it, then in that case memory-wise its same as what rmaddy solution takes. But still this solution is superior since, NSSet
creation time is far more than NSArray
- source.
UPDATE2: Updated to make the answer more comprehensive incase one array is bigger than other.
Upvotes: 9
Reputation: 128
Just like rmaddy said, those NSArrays are not equal. Try this:
-(BOOL)compareArrayIgnoreIndexes:(NSArray*)arrayOne toArray:(NSArray*)arrayTwo{
NSSet *setOne=[[NSSet alloc]initWithArray:arrayOne];
NSSet *setTwo=[[NSSet alloc]initWithArray:arrayTwo];
return [setOne isEqualToSet:setTwo];
}
Upvotes: 7
Reputation: 1759
I found the solution,,we can achieve that by sorting the array elements
NSArray *arr1 = [[NSArray alloc]initWithObjects:@"a2223a",@"ab33b",@"a1acdf",@"ac23c45", nil];
NSArray *arr11 = [arr1 sortedArrayUsingSelector:@selector(localizedCompare:)];
NSArray *arr2 = [[NSArray alloc]initWithObjects:@"ab33b",@"ac23c45",@"a1acdf",@"a2223a", nil];
NSArray *arr22= [arr2 sortedArrayUsingSelector:@selector(localizedCompare:)];
if([arr11 isEqualToArray:arr22])
{
NSLog(@"equal");
}
else
{
NSLog(@"Not equal");
}
Upvotes: 1
Reputation: 318794
Those two arrays are not equal. Two arrays are equal is they both have the same objects in the same order.
If you want to compare with no regard to order then you need to use two NSSet
objects.
NSSet *set1 = [NSSet setWithArray:arr1];
NSSet *set2 = [NSSet setWithArray:arr2];
if ([set1 isEqualToSet:set2]) {
// equal
}
Upvotes: 38