web-dev-qa-db-ja.com

あるNSArray内のオブジェクトを別の配列から減算します

2つのNSArrayがあります。

NSArray *wants = [NSArray arrayWithObjects:
                  @"apples", 
                  @"oranges", 
                  @"pineapple", 
                  @"mango", 
                  @"strawberries", 
                  nil];
NSArray *needs = [NSArray arrayWithObjects:
                  @"apples", 
                  @"pineapple", 
                  @"strawberries", 
                  nil];

そして、私はそれらをXORしたいと思います。何かのようなもの wants - needs私が残したのは

[NSArray arrayWithObjects:
@"oranges", 
@"mango", 
nil];

私は通常、重いループを経験しますが、もっと実用的な方法があると確信しています。代わりに何をすべきですか?

32
Jacksonkr

このようなもの?

NSMutableArray *array = [NSMutableArray arrayWithArray:wants];
[array removeObjectsInArray:needs];
59
Kirby Todd

Kirbyの答えは問題ありませんが、配列内の要素の順序を気にしない場合は、代わりにセットを使用する必要があります。順序が重要な場合は、NSOrderedSetを検討してください。 -minusSet:を使用するか、後者の場合は-minusOrderedSet:メソッドを使用できます。

8
Ken Thomases

述語を使うのはどうですか?

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", needs];
NSArray *wants_needs = [wants filteredArrayUsingPredicate:predicate];
8
Gyfis

2つの仮定が与えられます:順序が重要ではない(または復元できる-たとえば、配列が今ソートされている場合)*、およびどちらの配列にもアイテムが複数回表示されない(ただし、これにはカウントされたセットを使用できます)、セットは良い選択かもしれません。

2つのセットのXOR(厳密には対称差)は、和集合から共通部分を引いたものです。

NSMutableSet * unioned = [NSMutableSet setWithArray:wants];
[unioned unionSet:[NSSet setWithArray:needs]];
NSMutableSet * intersection = [NSMutableSet setWithArray:needs];
[intersection intersectSet:[NSSet setWithArray:wants]];

[unioned minusSet:intersection];

*順序が重要な場合は、 NSOrderedSet を使用できます。

2
Josh Caswell

これを試して:

NSArray *NSArray_XOR(NSArray *arr1, NSArray *arr2)
{
    NSMutableArray *results = [NSMutableArray array];

    for (int i = 0; i < arr1.count; i++) {
        id obj = [arr1 objectAtIndex:i];

        if (![arr2 containsObject:obj])
            [results addObject:obj];
    }

    for (int i = 0; i < arr2.count; i++) {
        id obj = [arr2 objectAtIndex:i];

        if (![arr1 containsObject:obj])
            [results addObject:obj];
    }

    // make a unmutable copy of the array.
    return [NSArray arrayWithArray:results];
}
0