LoginSignup
36
34

More than 5 years have passed since last update.

NSArrayの差分を取る

Last updated at Posted at 2013-01-04

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

使い方


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

36
34
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
34