Фильтрация массива массивов, содержащих словарь, с помощью NSPredicate

У меня есть массив с названием charactersAndDescriptions, который содержит несколько массивов, и в каждом из этих массивов есть NSDictionary с двумя ключами / значениями. Выглядит это так:

введите описание изображения здесь

Мне нужно отфильтровать этот массив по значению ключа desc, сравнивая его со строковой переменной searchText (и он должен возвращать результаты, в которых эта строка существует где-нибудь в описании). Я хочу, чтобы возвращаемая структура была такой же, как исходная - массивы, содержащие словарь внутри массива. Вот мой код:

NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"desc contains[c] %@", searchText];
self.resultsArray = [self.charactersAndDescriptions filteredArrayUsingPredicate:resultPredicate];

Проблема в том, что self.resultsArray всегда возвращает 0 объектов. Я не понимаю, почему это так. Я рассматривал вопросы здесь, где у них был только один массив словарей, но они не могли найти ни одного для вложенных массивов. Надеюсь, ты сможешь помочь, спасибо!


person Jordan H    schedule 14.04.2014    source источник
comment
Вам нужно провести глубокий поиск, так как это многоуровневый массив   -  person Michael King    schedule 14.04.2014
comment
Я хочу, чтобы возвращаемая структура была такой же, как и исходная - по-прежнему массивы словаря в массиве. Как мне выполнить глубокий поиск?   -  person Jordan H    schedule 14.04.2014


Ответы (1)


Я не уверен, что вы можете сделать это с помощью одного предиката. Но вы можете перебирать отдельные массивы словарей, фильтровать их и добавлять отфильтрованный список к вашему окончательному массиву. Попробуйте что-то вроде этого:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"desc contains[c] %@", searchText];
NSMutableArray *finalColletion = [NSMutableArray array];
for (NSArray *temp in self.charactersAndDescriptions) {
    NSArray *result =[temp filteredArrayUsingPredicate:predicate];
    if([result count] > 0) {
        [finalColletion addObject:result];
    }
}
person Shanti K    schedule 14.04.2014
comment
+1, но проверка [result count] > 0 не позволит вашему коду создать выходной массив, соответствующий входному массиву. Проверка не требуется, поскольку filteredArrayUsingPredicate вернет действительный пустой массив, если совпадений нет. - person user3386109; 14.04.2014
comment
«filterArrayUsingPredicate» вернет пустой массив, если совпадений нет .. нет необходимости добавлять его в окончательный результирующий массив. Отсюда и проверка .. Почему он сначала будет генерировать выходной массив? Он сгенерирует действительный выходной массив - person Shanti K; 14.04.2014
comment
Индексы массивов верхнего уровня не будут совпадать, если массив результатов не включает пустые массивы, но это может иметь или не иметь значения в зависимости от того, как он использует массив результатов. - person user3386109; 14.04.2014
comment
Это действительно важно, только чтобы немного упростить код при заполнении методов источника данных, поэтому я удалил этот оператор if. Огромное спасибо вам обоим! Это была последняя часть головоломки, и теперь мои поиски работают идеально, и я могу немного отдохнуть сегодня вечером. :) - person Jordan H; 14.04.2014