NSArray
и NSMutableArray
предоставить методы для фильтрации содержимого массива. NSArray
предоставляет filterArrayUsingPredicate: который возвращает новый массив, содержащий объекты в получателе, соответствующие указанному предикату. NSMutableArray
добавляет filterUsingPredicate: который оценивает содержимое получателя по указанному предикату и оставляет только совпадающие объекты. Эти методы проиллюстрированы в следующем примере.
NSMutableArray *array =
[NSMutableArray arrayWithObjects:@"Bill", @"Ben", @"Chris", @"Melissa", nil];
NSPredicate *bPredicate =
[NSPredicate predicateWithFormat:@"SELF beginswith[c] 'b'"];
NSArray *beginWithB =
[array filteredArrayUsingPredicate:bPredicate];
// beginWithB contains { @"Bill", @"Ben" }.
NSPredicate *sPredicate =
[NSPredicate predicateWithFormat:@"SELF contains[c] 's'"];
[array filteredArrayUsingPredicate:sPredicate];
// array now contains { @"Chris", @"Melissa" }
Есть множество способов сделать это, но самый изящный, безусловно, использует
[NSPredicate predicateWithBlock:]
:Я думаю, это настолько лаконично, насколько это возможно.
Swift:
Тем, кто работает с
NSArray
s в Swift, вы можете предпочесть еще более краткую версию:filter
- это просто методArray
(NSArray
неявно связан с SwiftArray
). Он принимает один аргумент: замыкание, которое принимает один объект в массиве и возвращаетBool
. В вашем закрытии просто вернитесьtrue
для любых объектов, которые вы хотите в фильтрованном массиве.источник
NSPredicate predicateWithBlock:
API.bindings
Словарь может содержать привязки переменных для шаблонов.Основываясь на ответе Клея Бриджеса, вот пример фильтрации с использованием блоков (измените
yourArray
имя переменной массива иtestFunc
имя вашей функции тестирования):источник
filteredArrayUsingPredicate
на то, что он более компактный, тот факт, что вы не используете никаких предикатов, как бы скрывает цель.Implicit conversion of 'NSUInteger' (aka 'unsigned long') to 'NSIndexSet * _Nonnull' is disallowed with ARC
... он ожидает NSIndexSetsindexOfObjectPassingTest
вместоindexesOfObjectsPassingTest
. Легко пропустить, но большая разница :)Если у вас OS X 10.6 / iOS 4.0 или новее, вам, вероятно, лучше использовать блоки, чем NSPredicate. Просмотрите
-[NSArray indexesOfObjectsPassingTest:]
или напишите свою собственную категорию, чтобы добавить удобный-select:
или-filter:
метод ( пример ).Хотите, чтобы кто-то еще написал эту категорию, протестировал ее и т. Д.? Проверьте BlocksKit ( массив документов ). И есть еще много примеров, которые можно найти, например, при поиске по запросу «nsarray block category select» .
источник
Предполагая, что все ваши объекты относятся к одному типу, вы можете добавить метод в качестве категории их базового класса, который вызывает функцию, которую вы используете для своих критериев. Затем создайте объект NSPredicate, который ссылается на этот метод.
В какой-то категории определите свой метод, который использует вашу функцию
Тогда везде, где вы будете фильтровать:
Конечно, если ваша функция сравнивается только со свойствами, доступными из вашего класса, может быть проще преобразовать условия функции в строку предиката.
источник
NSPredicate
является способом благодаря NeXTstep о построении условия для фильтрации коллекции (NSArray
,NSSet
,NSDictionary
).Например, рассмотрим два массива
arr
иfilteredarr
:у filterarr обязательно будут элементы, содержащие только символ c.
чтобы было легко запомнить тех, у кого мало фона sql
1) выберите * из таблицы -> сборник
2) column1 как '% a%' ->
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",@"c"];
3) выберите * from tbl, где column1, например '% a%' ->
надеюсь, это поможет
источник
NSArray + Xh
NSArray + Xm
Вы можете скачать эту категорию здесь
источник
Оформить заказ в этой библиотеке
https://github.com/BadChoice/Collection
Он поставляется с множеством простых функций массива, чтобы никогда больше не писать цикл
Итак, вы можете просто сделать:
или
источник
Лучший и простой способ - создать этот метод и передать массив и значение:
источник