16

我有两个NSArrays ,其中数组的对象相同但可能位于不同的索引中。无论它们的索引如何,它都应该打印两者相等。

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

上面的代码正在打印'Not equal',但它应该打印'Equal'。我怎样才能做到这一点?

4

7 回答 7

36

这两个数组不相等。两个数组是相等的,它们都以相同的顺序具有相同的对象。

如果您想在不考虑顺序的情况下进行比较,那么您需要使用两个NSSet对象。

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

if ([set1 isEqualToSet:set2]) {
    // equal
}
于 2012-12-11T06:56:20.930 回答
19

这里的大多数答案实际上不适用于相当常见的情况(请参阅他们的评论)。有一个非常好的数据结构可以解决这个问题:NSCountedSet

计数集是无序的,但确实关心存在的项目数,因此您最终不会得到@[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);
于 2014-01-15T22:05:36.647 回答
9

尝试这个。我正在做的是复制你的第一个数组并从第二个数组中删除复制元素。如果它为空,则它相等,否则不相等。

这比@rmaddy 解决方案的内存占用更少。您只创建一个数组的副本,而不是两个数组...

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:如果您想arr2在此之后使用,那么它已被更改。您需要对其进行复制,然后在这种情况下,在内存方面它与 rmaddy 解决方案所采用的相同。但是这个解决方案仍然是优越的,因为创建时间远远NSSet超过NSArray-source 。

UPDATE2:更新以使答案更全面,以防一个数组大于另一个数组。

于 2012-12-11T06:58:47.873 回答
7

就像 rmaddy 说的,那些 NSArray 是不相等的。尝试这个:

-(BOOL)compareArrayIgnoreIndexes:(NSArray*)arrayOne toArray:(NSArray*)arrayTwo{
    NSSet *setOne=[[NSSet alloc]initWithArray:arrayOne];
    NSSet *setTwo=[[NSSet alloc]initWithArray:arrayTwo];
    return [setOne isEqualToSet:setTwo];
}
于 2012-12-11T07:26:23.407 回答
1
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.
于 2012-12-11T10:26:33.030 回答
1

我找到了解决方案,我们可以通过对数组元素进行排序来实现

 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");
    }
于 2012-12-11T07:04:28.383 回答
-2

另一种选择是将 NSArrays 转换为 JSON 字符串,并使用 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;
}

我很好奇所有这些方法的性能比较。

于 2015-03-10T15:14:10.987 回答