Как искать NSSet или NSArray для объекта, который имеет конкретное значение для конкретного свойства? - PullRequest
50 голосов
/ 19 июня 2010

Как искать NSSet или NSArray для объекта, который имеет определенное значение для определенного свойства?

Пример: у меня есть NSSet с 20 объектами, и у каждого объекта есть свойство type. Я хочу получить первый объект, который имеет [theObject.type isEqualToString:@"standard"].

Я помню, что можно было как-то использовать предикаты для такого рода вещей, верно?

Ответы [ 4 ]

78 голосов
/ 19 июня 2010
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type == %@", @"standard"];
NSArray *filteredArray = [myArray filteredArrayUsingPredicate:predicate];
id firstFoundObject = nil;
firstFoundObject =  filteredArray.count > 0 ? filteredArray.firstObject : nil;

NB. Понятие первый найденный объект в NSSet не имеет смысла, так как порядок объектов в наборе не определен.

17 голосов
/ 21 июня 2010

Вы можете получить отфильтрованный массив, как описали Джейсон и Оле, но, поскольку вам нужен только один объект, я бы использовал - indexOfObjectPassingTest: (если он в массиве) или -objectPassingTest: (если он в наборе) иизбегайте создания второго массива.

15 голосов
/ 16 августа 2013

Обычно я использую indexOfObjectPassingTest:, так как мне удобнее выражать свой тест в коде Objective-C, а не в синтаксисе NSPredicate.Вот простой пример (представьте, что integerValue на самом деле было свойством):

NSArray *array = @[@0,@1,@2,@3];
NSUInteger indexOfTwo = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return ([(NSNumber *)obj integerValue] == 2);
}];
NSUInteger indexOfFour = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return ([(NSNumber *)obj integerValue] == 4);
}];
BOOL hasTwo = (indexOfTwo != NSNotFound);
BOOL hasFour = (indexOfFour != NSNotFound);
NSLog(@"hasTwo: %@ (index was %d)", hasTwo ? @"YES" : @"NO", indexOfTwo);
NSLog(@"hasFour: %@ (index was %d)", hasFour ? @"YES" : @"NO", indexOfFour);

Вывод этого кода:

hasTwo: YES (index was 2)
hasFour: NO (index was 2147483647)
4 голосов
/ 19 июня 2010
NSArray* results = [theFullArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF.type LIKE[cd] %@", @"standard"]];
...