Если вы делаете копию массива с некоторыми пунктами отфильтровываются, а затем сделать новую изменяемый массив, итерацию над оригиналом и добавить к копии на лету, как другие предложили для этого ответа. Но ваш вопрос говорит об удалении из существующего (предположительно изменяемого) массива.
Хотя итерации, можно создать массив объектов для удаления, а затем удалить их впоследствии:
NSMutableArray *thePeople = ...
NSString *hairColorToMatch = ...
NSMutableArray *matchingObjects = [NSMutableArray array];
for (People *person in thePeople) {
if (person.hairColor isEqualToString:hairColorToMatch])
[matchingObjects addObject:person];
[thePeople removeObjects:matchingObjects];
Но это создает временный массив, который вы могли бы подумать расточительно и, что более важно, это трудно см. removeObjects:
, очень эффективный. Кроме того, кто-то упомянул что-то о массивах с повторяющимися элементами, это должно работать в этом случае, но не было бы лучшим, причем каждый дубликат также использовался во временном массиве и дублировании в пределах removeObjects:
.
Можно итератировать по индексу и удалить, как вы идете, но это делает логику цикла довольно неудобной. Вместо этого я хотел бы собрать индексы в наборе индекса и снова, удалите потом:
NSMutableIndexSet *matchingIndexes = [NSMutableIndexSet indexSet];
for (NSUInteger n = thePeople.count, i = 0; i < n; ++i) {
People *person = thePeople[i];
if ([person.hairColor isEqualToString:hairColorToMatch])
[matchingIndexes addIndex:i];
}
[thePeople removeObjectsAtIndexes:matchingIndexes];
Я считаю, что индексные наборы имеют очень низкие накладные расходы, так что это почти так же эффективно, как вы получите и трудно испортить. Другое дело, что удаление в пакете в конце похоже на то, что возможно, что Apple оптимизировала removeObjectsAtIndexes:
, чтобы быть лучше, чем последовательность removeObjectAtIndex:
. Таким образом, даже с накладными расходами на создание структуры данных набора индексов, это может привести к удалению «на лету» во время итерации. Это тоже очень хорошо работает, если массив имеет дубликаты.
Если вместо этого, вы действительно делаете отфильтрованного копию, то я думал, что некоторые KVC
коллекции оператора вы можете использовать (я читал о тех, в последнее время, вы можете сделать некоторые сумасшедшие вещи с теми, по NSHipster & Guy English). По-видимому, нет, но близко к этому, необходимо использовать KVC и NSPredicate в этом несколько многословной линии:
NSArray *subsetOfPeople = [allPeople filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:@"SELF.hairColor != %@", hairColorToMatch]];
ли идти вперед и создать категорию на NSArray
, чтобы сделать вещи более краткими для вашего кода, filterWithFormat:
или что-то.
(все проверялось, набранный непосредственно в SO)
Сортировка ли? Есть ли дубликаты? Это теоретический вопрос, или у вас есть определенные проблемы с производительностью с вашим кодом? Если последнее, не могли бы вы дать более подробную информацию? Кроме того, чтобы быть ясным, вы конкретно ссылаетесь на мутацию существующего 'NSMutableArray' и не генерируете новый массив, который не содержит всех коричневоволосых людей в оригинале, - это правильно? –
нет, может быть, нет, нет, да –