Help us understand the problem. What is going on with this article?

NSArrayの差分を取る

More than 5 years have passed since last update.

カテゴリ拡張でつくってみた。

使い方

NSArray* aArray = @[@"a", @"b", @"c", @"d"];
NSArray* bArray = @[@"b", @"c", @"d", @"e", @"f"];

NSArray* newArray = [aArray difference:bArray];
NSLog(@"diff : %@", [newArray description]);

/* diff : a, e, f */

実装

1/5追記

Twitterにて「NSOrderedSet使って順番も保持したら」とツッコミいただきました。

NSArray+Difference.m
@implementation NSArray (Difference)

- (NSArray*)difference:(NSArray*)otherArray
{
    NSMutableOrderedSet* allSet = [NSMutableOrderedSet orderedSetWithArray:self];
    [allSet addObjectsFromArray:otherArray];

    NSMutableOrderedSet* duplicateSet = [NSMutableOrderedSet orderedSetWithArray:self];
    [duplicateSet intersectOrderedSet:[NSOrderedSet orderedSetWithArray:otherArray]];

    [allSet minusOrderedSet:duplicateSet];
    return [allSet array];
}

@end

これなら順番を保持したいとき、そうでないときのどちらにも対応できますね。
用途に応じて、ここから更に拡張もできそうです。
ありがとうございます!



1/4追記

コメントにていただいたアドバイスを元に書き換えてみました。

NSArray+Difference.m
@implementation NSArray (Difference)

- (NSArray*)difference:(NSArray*)otherArray
{
    // まとめる
    NSMutableSet* allSet = [NSMutableSet setWithArray:self];
    [allSet addObjectsFromArray:otherArray];

    // 重複する要素のみ抜き出して、
    NSMutableSet* duplicateSet = [NSMutableSet setWithArray:self];
    [duplicateSet intersectSet:[NSSet setWithArray:otherArray]];

    // 削除
    [allSet minusSet:duplicateSet];
    return [allSet allObjects];
}

@end

すっきり!



前のも残しておきます。

NSArray+Difference.m
@implementation NSArray (Difference)

- (NSArray*)difference:(NSArray*)otherArray
{
    // 配列をまとめる
    NSArray* all = [self arrayByAddingObjectsFromArray:otherArray];

    // 配列の中身をキーに、それぞれの数を格納
    NSMutableDictionary* dic = [NSMutableDictionary dictionary];
    for (NSString* key in all) {
        if (![dic hasKey:key]) {
            [dic setObject:@(1) forKey:key];
        } else {
            NSInteger num = [[dic objectForKey:key] integerValue];
            num++;
            [dic setObject:@(num) forKey:key];
        }
    }

    // 値が1のものだけ追加して返す
    NSMutableArray* res = [NSMutableArray array];
    for (NSString* key in [dic allKeys]) {
        if ([[dic objectForKey:key] integerValue] == 1) {
            [res addObject:key];
        }
    }
    return res;
}

@end

参考

配列の差分 PerlとObjective-C

NSMutableSet Class Reference

ar_tama
software developer / sound designer [Perl, Objective-C, ActionScript, openFrameworks, etc..] http://aratamakoto.com
http://aratamakoto.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away