Вопрос по nsarray, foundation, objective-c, nspredicate – NSP Предикатная фильтрация «ИЛИ» на основе NSArray ключей

8

Рассмотрим следующий NSArray:

NSArray *dataSet = [[NSArray alloc] initWithObjects:
                 [NSDictionary dictionaryWithObjectsAndKeys:@"abc", @"key1", @"def", @"key2", @"hij", @"key3", nil], 
                 [NSDictionary dictionaryWithObjectsAndKeys:@"klm", @"key1", @"nop", @"key2", nil], 
                 [NSDictionary dictionaryWithObjectsAndKeys:@"qrs", @"key2", @"tuv", @"key4", nil], 
                 [NSDictionary dictionaryWithObjectsAndKeys:@"wxy", @"key3", nil], 
                 nil];

Я могу отфильтровать этот массив, чтобы найти объекты словаря, которые содержатkey key1

// Filter our dataSet to only contain dictionary objects with a key of 'key1'
NSString *key = @"key1";
NSPredicate *key1Predicate = [NSPredicate predicateWithFormat:@"%@ IN [email protected]", key];
NSArray *filteretSet1 = [dataSet filteredArrayUsingPredicate:key1Predicate];
NSLog(@"filteretSet1: %@",filteretSet1);

Который соответственно возвращает:

filteretSet1: (
        {
        key1 = abc;
        key2 = def;
        key3 = hij;
    },
        {
        key1 = klm;
        key2 = nop;
    }
)

Теперь я хочу отфильтровать набор данных для объектов словаря, содержащихANY ключей в NSArray.

Например, используя массив:NSArray *keySet = [NSArray arrayWithObjects:@"key1", @"key3", nil]; Я хочу создать предикат, который возвращает и массивany объекты словаря, которые содержат либо «ключ1»;or  & APOS; ключ3 & APOS; (т.е. в этом примере будут возвращены все объекты словаря, кроме третьего объекта - так как он не содержит ни 'a key;' key1 ';or & APOS; ключ3 & APOS;).

Есть идеи, как мне этого добиться? Должен ли я использовать составной предикат?

Ваш Ответ

3   ответа
1

вы также можете использовать блок для большей детализации:

NSArray *filter = [NSArray arrayWithObjects:@"key1", @"key3",nil];

NSPredicate *filterBlock = [NSPredicate predicateWithBlock: ^BOOL(id obj, NSDictionary *bind){        
    NSDictionary *data = (NSDictionary*)obj;

    // use 'filter' and implement your logic and return YES or NO
}];

[dataSet filteredArrayUsingPredicate:filterBlock];

Это может быть изменено, как вы хотите, возможно, в рамках своего собственного метода.

1

   NSString *key = @"key1";
   NSString *key1 = @"key3";
   NSPredicate *key1Predicate = [NSPredicate predicateWithFormat:@"%@ IN [email protected] OR %@ IN [email protected]",key,key1];
   NSArray *filteretSet1 = [dataSet filteredArrayUsingPredicate:key1Predicate];
   NSLog(@"filteretSet1: %@",filteretSet1);

Отлично работает для меня Надеюсь, полезно

Спасибо за ваш вклад. Я знаю, что могу использовать ИЛИ. Причина, по которой я хотел использовать массив, была для любого количества ключей, а не для двух ключей. So Over It
9

ANY операторNSPredicate охватывает это:

key1", @"key3", nil];

NSPredicate *key1Predicate = [NSPredicate predicateWithFormat:@"any [email protected] in %@", keys];
Хорошо, так что это не чувствительно к регистру. Спасибо!
any было то, что мне не хватало. Я не знаю, почему я нахожу NSPredicate настолько сложным, чтобы разобраться в этом. Спасибо за Ваш ответ. Моноло +1 :) So Over It
этот регистр чувствителен? Я узнаю в конце концов, но я надеюсь, что это уже. Я прокомментирую позже.
@ coolcool1994 ANY и IN (и SELF) в предикате выше не чувствительны к регистру (на самом деле я часто пишу их во всех заглавных буквах, чтобы они выделялись), имена ключей / методов, так что@allKeys is с учетом регистра.

Похожие вопросы