異なる基準に従ってリストに追加された名前を含む3つのNSMutableArrayがあります。
これが私の配列の疑似コードです:
NSMutableArray *array1 = [@"Jack", @"John", @"Daniel", @"Lisa"];
NSMutableArray *array2 = [@"Jack", @"Bryan", @"Barney", @"Lisa",@"Penelope",@"Angelica"];
NSMutableArray *array3 = [@"Jack", @"Jerome", @"Dan", @"Lindsay", @"Lisa"];
これらの3つの配列の共通部分を含む4番目の配列を見つけたいと思います。この場合、たとえば次のようになります。
NSMutableArray *array4 = [@"Jack",@"Lisa"];
3つの配列すべてに、ジャックとリサが要素として含まれているからです。これを簡単に行う方法はありますか?
NSMutableSet
を使用:
NSMutableSet *intersection = [NSMutableSet setWithArray:array1];
[intersection intersectSet:[NSSet setWithArray:array2]];
[intersection intersectSet:[NSSet setWithArray:array3]];
NSArray *array4 = [intersection allObjects];
これに関する唯一の問題は、要素の順序付けが失われることですが、(この場合)それで問題ないと思います。
コメントで指摘されているように(ありがとう Q8 !)、iOS 5およびOS X 10.7はNSOrderedSet
という新しいクラスを追加しました(Mutable
サブクラスを使用)これにより、順序を維持しながらこれらの同じ交差操作を実行できます。
この投稿 をご覧ください。
つまり、NSArrayの代わりにNSSetを使用できる場合、それは取るに足らないことです(NSMutableSetにはintersectSet:
)。
それ以外の場合は、NSArrayからNSSetを構築して、上記のケースに戻ることができます。
NSMutableArray *first = [[NSMutableArray alloc] initWithObjects:@"Jack", @"John", @"Daniel", @"Lisa",nil];
NSMutableArray *seconds =[[NSMutableArray alloc] initWithObjects:@"Jack", @"Bryan", @"Barney", @"Lisa",@"Penelope",@"Angelica",nil];
NSMutableArray *third = [ [ NSMutableArray alloc]init];
for (id obj in first) {
if ([seconds containsObject:obj] ) {
[third addObject:obj];
}
}
NSLog(@"third is : %@ \n\n",third);
出力:
3番目は:(
Jack,
Lisa
)
これはNSSet
アプローチよりもきれいで、元の順序を失うことはありません。
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self IN %@ AND self IN %@", array2, array3];
NSArray *array4 = [array1 filteredArrayUsingPredicate:predicate];