NSPredicate на NSArray для поиска любого объекта

У меня есть массив объектов с именами, адресами, tel. nos и т.д.

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

У меня есть что-то подобное:

-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
    // Update the filtered array based on the search text and scope.
    // Remove all objects from the filtered search array


    [self.searchResults removeAllObjects];
    // Filter the array using NSPredicate
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",searchText];
    searchResults = [NSMutableArray arrayWithArray:[contactArray filteredArrayUsingPredicate:predicate]];
}

Это вызывает исключение "Нельзя использовать в/содержит оператор с коллекцией".

UPDATE. Теперь я могу выполнить поиск по трем полям. Когда я добавляю четвертый (в любой последовательности), я получаю это исключение: "Невозможно разобрать строку формата..."

Код Predicate теперь:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.narrative contains[c] %@ OR SELF.category contains[c] %@ OR SELF.date contains[c] OR SELF.name contains[c] %@", searchText, searchText, searchText, searchText];

     searchResults = [NSMutableArray arrayWithArray:[allDreams filteredArrayUsingPredicate:predicate]];

Есть три предела предикатных полей поиска? Как мне обойти это? Еще раз спасибо.

Ответ 1

Просто используйте предикатную строку, которая проверяет их все:

@"name contains[cd] %@ OR address contains[cd] %@"

вы можете добавить столько, сколько хотите.

Единственным недостатком является то, что вам нужно будет добавить одну и ту же строку поиска для каждого поля, которое вы хотите проверить, что может показаться немного уродливым.

Если ваши объекты являются словарями, то есть способ действительно искать все значения, не зная их имена во время компиляции, используя подзапрос.

Он работает следующим образом:

@"subquery([email protected], $av, $av contains %@)[email protected] > 0"

Он использует специальный ключ @allValues (или вызов метода, если вы предпочитаете) для объектов словаря и использует его для фильтрации любого значения, содержащего строку поиска. Если какой-либо найден (т.е. Счет положителен), объект включается в результаты.

Обратите внимание, что это будет проверять все значения без разбора, даже те, которые вы не хотите включать, если они есть в вашем словаре.

Ответ 2

Я думаю, что ваш элемент массива не является чистой строкой, верно?

Предположим, что ваш элемент массива содержит атрибут name (даже это словарь), вы можете искать его таким образом:

NSPredicate * predicate =
  [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@ OR name LIKE[cd] %@", searchText, searchText];

здесь name может быть SELF.name.


ЗДЕСЬ официальный документ.