web-dev-qa-db-fra.com

Correspondance insensible à la casse NSPredicate sur une relation à plusieurs

J'implémente un champ de recherche où l'utilisateur peut taper une chaîne pour filtrer les éléments affichés dans une vue. Chaque objet affiché a une relation keywords à plusieurs, et je voudrais pouvoir filtrer les objets en fonction de leurs mots clés. Chaque objet mot-clé possède une propriété name, j'ai donc configuré un NSPredicate pour effectuer le filtrage qui ressemble à ceci:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"keywords.name CONTAINS %@", self.searchString];

Cela fonctionne, mais le problème est que la recherche est sensible à la casse, donc si le mot clé a une majuscule mais que l'utilisateur tape en minuscules, aucune correspondance n'est trouvée. J'ai essayé la modification suivante:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"keywords.name CONTAINS[c] %@", self.searchString];

Mais cela ne fait aucune différence dans la sensibilité à la casse de la correspondance. Existe-t-il un moyen de faire cette correspondance insensible à la casse en utilisant simplement un prédicat simple? Ou devrais-je implémenter une sorte d'accesseur personnalisé sur la classe de mots-clés, par exemple écrire une méthode lowercaseName et la comparer à une version en minuscule de la chaîne de recherche?

Addendum: après une exploration plus approfondie, la solution de contournement d'ajout d'un accessoire personnalisé fonctionne correctement pour une utilisation manuelle de NSPredicate, mais ne fonctionne pas du tout lors de l'utilisation de NSFetchRequest avec Core Data, qui ne fonctionne que lors de la requête d'attributs définis dans le modèle Core Data.

64
Brian Webster

Si je vous comprends bien, vous voulez que votre prédicat soit vrai chaque fois qu'un nom de mot clé correspond à la chaîne de recherche. Pour cela, vous devez tester avec le mot-clé ANY comme ceci:

[NSPredicate predicateWithFormat:@"ANY keywords.name CONTAINS[c] %@", ...];

Cela recherchera les mots-clés et retournera vrai si l'un de ces noms de mots-clés contient votre chaîne de recherche.

87
Alfonso

Je crois que la réponse est:

[NSPredicate predicateWithFormat:@"keywords.name CONTAINS[cd] %@", self.searchString];

Les comparaisons de chaînes sont par défaut sensibles à la casse et aux signes diacritiques. Vous pouvez modifier un opérateur en utilisant les caractères clés c et d entre accolades pour spécifier respectivement la casse et l'insensibilité diacritique, par exemple firstName BEGINSWITH [cd] $ FIRST_NAME.

Syntaxe de chaîne de format de prédicat

49
slatvick

Si vous essayez d'attraper uniquement les noms égaux mais avec une casse insensible, je pense que c'est la meilleure solution

[NSPredicate predicateWithFormat:@"ANY keywords.name LIKE[c] %@", ...];

Tu m'as beaucoup aidé. Merci les gars!!!

Dans mon cas, j'ai fait:

[NSPredicate predicateWithFormat:@"ANY name LIKE[c] %@", @"teste"];
13
wal

Si vous devez faire correspondre le mot clé mais que la recherche doit être sensible à la casse -in, vous devez utiliser NSPredicate(format: "keywords.name =[c] %@", self.searchString)

LIKE ne fonctionne pas sur les littéraux de chaîne.

6
netshark1000

Si vous voulez à la fois insensible à la casse et joker, utilisez ceci:

NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"(name like[c] '*%@*')",@"search"]];
1
Sven