NSPredicate без учета регистра соответствия для многих
Я реализую поле поиска, в котором пользователь может ввести строку для фильтрации элементов, отображаемых в представлении. Каждый отображаемый объект имеет отношение keywords
to-many, и я хотел бы иметь возможность фильтровать объекты на основе их ключевых слов. Каждый объект ключевого слова имеет свойство name
, поэтому я настроил NSPredicate для фильтрации, которая выглядит так:
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"keywords.name CONTAINS %@", self.searchString];
Это работает, но проблема в том, что поиск чувствителен к регистру, поэтому, если ключевое слово имеет заглавную букву, но пользователь вводит все строчные буквы, совпадений не найдено. Я пробовал следующую модификацию:
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"keywords.name CONTAINS[c] %@", self.searchString];
Но это не влияет на чувствительность к регистру. Есть ли способ сделать это нечувствительное к регистру сопоставление с использованием простого предиката? Или мне нужно будет реализовать какой-то пользовательский аксессуар в классе ключевого слова, например. написать метод lowercaseName
и сопоставить с нижней строкой строки поиска вместо?
Приложение:
После дальнейшего изучения обходной путь добавления пользовательского аксессора работает нормально для ручного использования NSPredicate, но не работает при использовании NSFetchRequest с Core Data, что работает только при запросе атрибутов, определенных в модели Core Data.
Ответы
Ответ 1
Если я правильно вас понимаю, вы хотите, чтобы ваш предикат был истинным, когда любое ключевое слово соответствует строке поиска. Для этого вам нужно проверить с помощью ЛЮБОГО ключевого слова следующим образом:
[NSPredicate predicateWithFormat:@"ANY keywords.name CONTAINS[c] %@", ...];
Это приведет к поиску ключевых слов и возврату true, если какое-либо из этих имен ключевых слов содержит вашу строку поиска.
Ответ 2
Я считаю, что ответ таков:
[NSPredicate predicateWithFormat:@"keywords.name CONTAINS[cd] %@", self.searchString];
Сравнение строк по умолчанию является случайным и диакритическим. Вы можете изменить оператора, используя ключевые символы c и d в квадратных скобках, чтобы указать регистр и диакритическую нечувствительность соответственно, например firstName BEGINSWITH [cd] $FIRST_NAME.
Синтаксис строки формата предиката
Ответ 3
Если вы пытаетесь поймать только имена равных, но с нечувствительным случаем, я думаю, что это лучшее решение
[NSPredicate predicateWithFormat:@"ANY keywords.name LIKE[c] %@", ...];
Ты мне очень помог. Спасибо, ребята!!!
В моем случае я сделал:
[NSPredicate predicateWithFormat:@"ANY name LIKE[c] %@", @"teste"];
Ответ 4
Если вы должны соответствовать ключевому слову, но поиск должен быть чувствительным к регистру в, тогда вы должны использовать NSPredicate(format: "keywords.name =[c] %@", self.searchString)
LIKE
не работает с строковыми литералами.
Ответ 5
Если вы хотите как нечувствительный к регистру, так и подстановочный знак, используйте это:
NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"(name like[c] '*%@*')",@"search"]];