web-dev-qa-db-ja.com

2つのアレイのコンテンツが等しいかどうかを比較するにはどうすればよいですか?

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

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

上記のコードは出力しています'等しくない'ですが、出力する必要があります'等しい'。これどうやってするの?

15
Ravi

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

順序に関係なく比較したい場合は、2つのNSSetオブジェクトを使用する必要があります。

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

if ([set1 isEqualToSet:set2]) {
    // equal
}
35
rmaddy

ここでの回答のほとんどは、実際にはかなり一般的なケースでは機能しません(コメントを参照)。この問題を解決する非常に優れたデータ構造があります: 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);
15
OC Rickard

これを試して。私がやっていることは、最初の配列のコピーを作成し、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の作成時間はNSArray - source よりはるかに長いため、このソリューションは優れています。

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

9

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];
}
5
dotAramis
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.
1
Abz Ios

私は解決策を見つけました、私たちは配列要素をソートすることによってそれを達成することができます

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

もう1つのオプションは、NSArrayを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;
}

これらすべての方法のパフォーマンス比較について知りたいと思います。

0
Mitch Cohen