Использование NSPredicate для фильтрации на основе нескольких ключей (НЕ значения для ключа)

У меня есть следующий NSArray, содержащий NSDictionary (ы):

NSArray *data = [[NSArray alloc] initWithObjects:
                 [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1], @"bill", [NSNumber numberWithInt:2], @"joe", nil],
                 [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:3], @"bill", [NSNumber numberWithInt:4], @"joe", [NSNumber numberWithInt:5], @"jenny", nil],
                 [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:6], @"joe", [NSNumber numberWithInt:1], @"jenny", nil],
                 nil];

Я хочу создать фильтрованный NSArray, который содержит только объекты, в которых NSDictionary сопоставляет несколько "ключей" с использованием NSPredicate.

Например:

  • фильтровать массив только для объектов NSDictionary, имеющих ключи "bill" и "joe" [желаемый результат: новый NSArray будет содержать первые два объекта NSDictionary]
  • фильтровать массив, чтобы содержать только объекты NSDictionary, которые имеют ключи "joe" и "jenny" [желаемый результат: новый NSArray будет содержать два последних объекта NSDictionary]

Может кто-нибудь объяснить формат NSPredicate для достижения этого?

Изменить: Я могу достичь аналогичного результата в желаемом NSPredicate, используя:

NSMutableArray *filteredSet = [[NSMutableArray alloc] initWithCapacity:[data count]];
NSString *keySearch1 = [NSString stringWithString:@"bill"];
NSString *keySearch2 = [NSString stringWithString:@"joe"];

for (NSDictionary *currentDict in data){
    // objectForKey will return nil if a key doesn't exists.
    if ([currentDict objectForKey:keySearch1] && [currentDict objectForKey:keySearch2]){
        [filteredSet addObject:currentDict];
    }
}

NSLog(@"filteredSet: %@", filteredSet);

Я предполагаю, что NSPredicate будет более элегантным, если он существует?

Ответ 1

я знаю только, чтобы объединить два условия: "value1" IN list AND 'value2' IN list "

self. @allKeys должен возвращать все ключи словаря (self - это каждый словарь в вашем массиве). Если вы не записываете его с префиксом @, тогда словарь будет искать ключ, который является "allKeys" вместо метода "- (NSArray *) allKeys"

Код:

NSArray* billAndJoe = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"%@ IN [email protected] AND %@ IN [email protected]" , @"bill",@"joe" ]];


NSArray* joeAndJenny = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"%@ IN [email protected] AND %@ IN [email protected]" , @"joe",@"jenny" ]]

Ответ 2

Поскольку словарь просто возвращает nil, если вы запрашиваете значение несуществующего ключа, достаточно указать, что значение должно быть не ноль. Формат, подобный приведенному ниже, должен охватывать ваш первый случай:

[NSPredicate predicateWithFormat: @"%K != nil AND %K != nil", @"bill", @"joe"]

Второй случай, с "joe" и "jenny", следует аналогичной схеме, конечно.