У меня есть 2 массива, один содержит набор идентификаторов, а другой - набор объектов (аналогично приведенному ниже):
NSArray *identifierArray = @[@100, @200, @300];
NSArray *peopleArray = @[@{@"id": @100, @"name": @"Ben"}, @{@"id": @200, @"name": @"Alex"}, @{@"id": @300, @"name": @"Sarah"}, @{@"id": @400,@"name": @"George"}, @{@"id": @500, @"name": @"Jessica"}];
Я хочу иметь возможность прокручивать peopleArray
и проверять, есть ли у какого-либо из объектов идентификатор, который отображается в identifierArray
. Если совпадение найдено, он должен удалить объект из identifierArray
, что приведет к:
NSArray *peopleArray = @[@{@"id": @400,@"name": @"George"}, @{@"id": @500, @"name": @"Jessica"}];
Я пробовал несколько вариантов циклов for для обхода каждого объекта, а затем для каждого идентификатора в peopleArray
, как показано ниже, но он не удаляет никаких объектов, хотя есть объекты, которые следует удалить.
for (NSNumber *id in activePeople) {
for (int i = 0; i < peopleArray.count; i++) {
if (id == [peopleArray[i] valueForKey:@"id"]) {
NSLog(@"Should remove...%@")
}
}
}
Может ли кто-нибудь указать мне, как я могу это сделать?
Скорее всего, вы не сможете использовать == для сравнения двух объектов в этом случае, а вместо этого используйте isEqual:
== сравнивает значения указателей. В вашем случае кажется, что они не будут такими же.
isEqual: вместо этого сравнивает сами объекты.
Чтобы повторно использовать свой код, вы можете попробовать следующее:
for (NSNumber *id in activePeople) {
for (int i = 0; i < peopleArray.count; i++) {
if ([id isEqual:[peopleArray[i] valueForKey:@"id"]) {
NSLog(@"Should remove...%@")
}
}
}
Только что попробовал, но, похоже, не удаляет объект (/ NSLog не выводит на консоль)?
Я предлагаю отказаться от циклов и использовать более современный блочный API indexesOfObjectsPassingTest
(который фактически существует с 2009 года в macOS 10.6 Snow Leopard и iOS 4.0).
NSArray *identifierArray = @[@100, @200, @300];
NSMutableArray *array = [@[@{@"id": @100, @"name": @"Ben"}, @{@"id": @200, @"name": @"Alex"}, @{@"id": @300, @"name": @"Sarah"}, @{@"id": @400,@"name": @"George"}, @{@"id": @500, @"name": @"Jessica"}] mutableCopy];
NSIndexSet *indexes = [array indexesOfObjectsPassingTest:^BOOL(NSDictionary *obj, NSUInteger idx, BOOL *stop) {
return [identifierArray containsObject:obj[@"id"]];
}];
[array removeObjectsAtIndexes:indexes];
NSLog(@"%@", array);
Или еще более эффективная фильтрация массива с помощью предиката (доступно начиная с macOS 10.4 Tiger и iOS 3.0 в 2005 году (!))
NSArray *identifierArray = @[@100, @200, @300];
NSArray *array = @[@{@"id": @100, @"name": @"Ben"}, @{@"id": @200, @"name": @"Alex"}, @{@"id": @300, @"name": @"Sarah"}, @{@"id": @400,@"name": @"George"}, @{@"id": @500, @"name": @"Jessica"}];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT id IN %@", identifierArray];
NSArray *result = [array filteredArrayUsingPredicate:predicate];
NSLog(@"%@", result);
Если значения id
должны быть строками, замените все вхождения @x00
на @"x00"
.
Учитывая оба попытки, но оба, похоже, не удаляют объекты с идентификаторами 100, 200 или 300. Я, должно быть, что-то упускаю ...
Оба фрагмента должны работать автономно. Идентификаторы действительно объекты NSNumber
?
А, думаю, я мог решить эту проблему, используя приведенный вами пример предиката, просто заменив predicateWithFormat:@"NOT id IN %@", identifierArray]
на predicateWithFormat:@"id == %@", identifierArray]
. Если вы сможете обновить свой ответ, я с радостью приму, надеюсь, поможет кому-то еще в будущем. Цените помощь!
Если вы хотите использовать хранить 400 и 500, как описано в вопросе, код правильный, @"id == %@", identifierArray
не может работать.
Ах, как вы это упомянули, я только что напечатал тип данных id
в array
в примере, и на самом деле это NSTaggedPointerString
, а id
в identifierArray
- это __NSCFNumber
, поэтому, должно быть, у меня это не сработало.
Работает отлично, моя вина ... соответствует двум типам данных и работает должным образом. Спасибо!
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что это домашнее задание