Поиск пересечения NSMutableArrays
У меня есть три NSMutableArray, содержащие имена, которые добавляются в списки в соответствии с различными критериями.
Вот псевдокод my arrays:
NSMutableArray *array1 = [@"Jack", @"John", @"Daniel", @"Lisa"];
NSMutableArray *array2 = [@"Jack", @"Bryan", @"Barney", @"Lisa",@"Penelope",@"Angelica"];
NSMutableArray *array3 = [@"Jack", @"Jerome", @"Dan", @"Lindsay", @"Lisa"];
Я хочу найти четвертый массив, который включает пересечение этих трех массивов. В этом случае, например, это будет:
NSMutableArray *array4 = [@"Jack",@"Lisa"];
Потому что все три массива имеют jack и lisa как элемент. Есть ли способ сделать это?
Ответы
Ответ 1
Используйте NSMutableSet
:
NSMutableSet *intersection = [NSMutableSet setWithArray:array1];
[intersection intersectSet:[NSSet setWithArray:array2]];
[intersection intersectSet:[NSSet setWithArray:array3]];
NSArray *array4 = [intersection allObjects];
Единственная проблема заключается в том, что вы теряете порядок элементов, но я думаю (в этом случае), что это нормально.
Как было отмечено в комментариях (спасибо, Q80!), iOS 5 и OS X 10.7 добавили новый класс под названием NSOrderedSet
(с Mutable
), который позволяет выполнять эти же операции пересечения, сохраняя при этом порядок.
Ответ 2
Действительно хороший учебник о пересечениях с использованием предикатов
Пересечения и различия массивов
Ответ 3
Посмотрите этот пост.
Короче: если вы можете использовать NSSet вместо NSArray, тогда это тривиально (NSMutableSet имеет intersectSet:
).
В противном случае вы можете построить NSSet из вашего NSArray и вернуться к приведенному выше случаю.
Ответ 4
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);
ВЫВОД:
третий: (
Jack,
Lisa
)
Ответ 5
Это более чистый, чем подход NSSet
, и вы не потеряете первоначальный порядок.
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self IN %@ AND self IN %@", array2, array3];
NSArray *array4 = [array1 filteredArrayUsingPredicate:predicate];
Ответ 6
Вот рабочий вариант из ссылок выше
NSPredicate *intersectPredicate = [NSPredicate predicateWithFormat:@"SELF IN %@", @[@500, @400, @600]];
NSArray *intersect = [@[@200, @300, @400] filteredArrayUsingPredicate:intersectPredicate];