Objective-C: цикл по массиву объектов и удаление объектов, которые соответствуют значению в другом массиве - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть 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...%@")
            }
        }
    }

Может кто-нибудь указать мне, как мне поступитьэто?

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Мое предложение - отбросить циклы и использовать более современный блочный 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"

0 голосов
/ 12 сентября 2018

Скорее всего, вы не можете использовать == для сравнения двух объектов в этом случае, но вместо этого используйте 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...%@")
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...