16

NSArray配列のオブジェクトは同じですが、インデックスが異なる可能性がある2つのがあります。インデックスに関係なく、両方が等しいと出力する必要があります。

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

これらの 2 つの配列は等しくありません。2 つの配列が等しいのは、両方とも同じオブジェクトが同じ順序である場合です。

順序に関係なく比較したい場合は、2 つの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

これを試して。私がやっていることは、最初の配列のコピーを作成し、2 番目の配列からコピー要素を削除することです。空の場合は等しく、そうでない場合は等しくありません。

これは、@rmaddy ソリューションよりもメモリ使用量が少なくなります。両方の配列ではなく、1 つの配列のみの複製を作成します...

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は -source よりもはるかに長いため、このソリューションは依然として優れていますNSArray

UPDATE2: 1 つの配列が他の配列よりも大きい場合に、回答をより包括的にするために更新されました。

于 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 に答える