2009-09-24 6 views
62

Sto implementando un campo di ricerca in cui l'utente può digitare una stringa per filtrare gli elementi visualizzati in una vista. Ogni oggetto che viene visualizzato ha una relazione to-many keywords e vorrei poter filtrare gli oggetti in base alle loro parole chiave. Ogni oggetto ha una proprietà parola chiave name, così ho istituito un NSPredicate per fare il filtraggio che assomiglia a questo:Corrispondenza senza distinzione tra maiuscole e minuscole NSPredicate su più rapporti

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

Questo funziona, ma il problema è che la ricerca è case-sensitive, quindi se il la parola chiave ha una lettera maiuscola ma l'utente digita tutto in minuscolo, non vengono trovate corrispondenze. Ho provato la seguente modifica:

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

Ma ciò non fa alcuna differenza nella sensibilità del caso della corrispondenza. C'è un modo per fare questo abbinamento insensibile alle maiuscole utilizzando solo un semplice predicato? O avrò bisogno di implementare una sorta di accesso personalizzato sulla classe di parole chiave, ad es. scrivere un metodo lowercaseName e confrontarlo con una versione in minuscolo della stringa di ricerca?

Addendum: Dopo ulteriori esplorazioni, la soluzione di aggiungere una funzione di accesso personalizzato funziona bene per uso manuale di NSPredicate, ma non funziona affatto quando si utilizza NSFetchRequest con Core Data, che funziona solo se l'interrogazione di attributi definiti nei dati Nucleo modello.

risposta

79

Se ho capito bene, volete che il vostro predicato per essere vero ogni volta che qualsiasi nome di parole chiave corrisponde alla stringa di ricerca. Per questo è necessario mettere alla prova con la parola chiave ANY come questo:

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

Questo cercherà le parole chiave e restituire true se una di queste parole chiave nome contiene la stringa di ricerca.

+1

Sapevo che doveva esserci un modo che mi mancava. Funziona come un fascino. Grazie! –

42

Credo che la risposta è:

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

String comparisons are by default case and diacritic sensitive. You can modify an operator using the key characters c and d within square braces to specify case and diacritic insensitivity respectively, for example firstName BEGINSWITH[cd] $FIRST_NAME.

Predicate Format String Syntax

+0

Questo è essenzialmente lo stesso del mio secondo tentativo pubblicato nella domanda originale, solo l'aggiunta della bandiera diacritica è diversa. Il problema è che questo non funziona quando il lato sinistro dell'espressione non è una stringa semplice. –

+1

Per me, l'opzione [d] mi ha dato questo errore: 'Terminazione dell'app a causa dell'eccezione non rilevata 'Opzione predicato non valida', motivo: 'NSDiacriticInsensitivePredicateOption non supportato per tipo di stringa'' – Zeb

+0

anche io. Ho avuto lo stesso errore. –

12

Se si sta cercando di catturare solo il uguale nomi ma con maiuscole e minuscole, penso che sia la soluzione migliore

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

Lei mi ha aiutato molto. Grazie ragazzi!!!

Nel mio caso ho fatto:

[NSPredicate predicateWithFormat:@"ANY name LIKE[c] %@", @"teste"]; 
+0

'LIKE' è l'operatore di corrispondenza glob (? *). Funzionerà correttamente solo se la stringa che passi per '% @' è un modello glob, perché il predicato lo interpreterà come uno; se la stringa non è un pattern glob, passarlo dove è previsto un glob causerà problemi. Usa == se vuoi l'uguaglianza rigorosa. –

+7

OH MAN !!!!!!!!!! Anche questo funziona .. == [c]. Non ho provato questo! Che cos'è il mondo della musica, l'ho cercato su google ma ... È un'espressione regolare? – wal

+0

No. I Glob sono il tipo di pattern che usi nella shell per abbinare più nomi di file contemporaneamente. –

1

Se si desidera sia case insensitive e jolly, utilizzare questo:

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

'NSPredicate * predicate = [NSPredicate predicateWithFormat: @" (nome come [c] '*% @ *') ", @" ricerca "];' è sufficiente. – Zeb

2

Se si deve abbinare la parola chiave, ma la ricerca deve essere maiuscole in sensibile quindi è necessario utilizzare NSPredicate(format: "keywords.name =[c] %@", self.searchString)

LIKE non funziona su stringhe letterali.

Problemi correlati