2012-12-21 5 views
12

Ho un oggetto Person che ha due proprietà NSString; firstName and lastName. Attualmente sto usando un NSPredicate in questo modo:Come unire due stringhe per NSPredicate, ovvero nome e cognome

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(firstName contains[cd] %@) OR (lastName contains[cd] %@)", searchText, searchText]; 

Così, per esempio, dire che sto cercando il nome "John Smith". Nella mia barra di ricerca se digito "Joh", verrà visualizzata l'opzione John Smith. Questo va bene, ma se digito "John Sm" diventerà vuoto.

Come unire firstName e lastName nel predicate così se stavo cercando "John Sm" allora John Smith sembrerebbe ancora come un'opzione.

Spero che abbia senso. Grazie.

EDIT: Per aggiungere un po 'maggiori chiarimenti, sto usando il metodo SearchDisplayController delegato:

-(void)filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope; 

e sto usando il predicate in questo modo:

newArray = [personObjectArray filteredArrayUsingPredicate:predicate]; 
+2

controllo qui per dare informazioni complete https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html – Deepak

+0

Ho letto che ma ho ancora don capisco come si fa – Chicken

+0

È possibile utilizzare meglio il dizionario o array in modo da poterlo implementare facilmente – Deepak

risposta

17

Prova questa,

NSString *text = @"John Smi"; 
NSString *searchText = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 

NSArray *array = [searchText componentsSeparatedByString:@" "]; 
NSString *firstName = searchText; 
NSString *lastName = searchText; 
NSPredicate *predicate = nil; 

if ([array count] > 1) { 
    firstName = array[0]; 
    lastName = array[1]; 
    predicate = [NSPredicate predicateWithFormat:@"(firstName CONTAINS[cd] %@ AND lastName CONTAINS[cd] %@) OR (firstName CONTAINS[cd] %@ AND lastName CONTAINS[cd] %@)", firstName, lastName, lastName, firstName]; 
} else { 
    predicate = [NSPredicate predicateWithFormat:@"firstName CONTAINS[cd] %@ OR lastName CONTAINS[cd] %@", firstName, lastName]; 
} 

NSArray *filteredArray = [people filteredArrayUsingPredicate:predicate]; 
NSLog(@"%@", filteredArray); 

Uscita:

(
     { 
     firstName = John; 
     lastName = Smith; 
    } 
) 

Qui il testo rappresenta il testo cercato. Il vantaggio di cui sopra è che, anche se si passa text = @"Smi Joh"; o text = @"John "; o text = @" smi"; o text = @"joh smi ";, verrà comunque visualizzato l'output sopra.

+0

Grazie a voi funziona alla grande tranne che per un piccolo problema. Diciamo che sono in procinto di digitare "john" con lo spazio, non appariranno risultati finché non inizierò a digitare il cognome, c'è un modo per mostrare ancora John Smith con "john" nella barra di ricerca? – Chicken

+0

Dovrebbe funzionare. Fammi controllare di nuovo. – iDev

+1

Sta funzionando bene anche per me. L'avevo provato prima di postare. Penso che ti sia mancato 'NSString * text = @" john "; NSString * searchText = [text stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]]; 'Sono sicuro che non stai facendo la seconda riga con il testo di ricerca prima di filtrare. Fondamentalmente è necessario rimuovere qualsiasi spazio iniziale o finale mentre si fa il filtraggio o fallirà. Quindi se non usi la seconda linea, fallirà. – iDev

1

è possibile concatenare i campi in due campi comuni (firstLastName e lastFirstName)

- (NSString *)firstLastName { 
     return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName]; 
} 

- (NSString *)lastFirstName { 
     return [NSString stringWithFormat:@"%@ %@", self.lastName, self.firstName]; 
} 

e poi filtrare su questi campi che utilizzano 'contiene [cd]'

[NSPredicate predicateWithFormat:@"(firstLastName contains[cd] %@) OR (lastFirstName contains[cd] %@)" , self.searchBar.text, self.searchBar.text]; 
+0

Questo non funzionerà nel predicato coredata, bro. – Eddie

0

La soluzione suggerita sopra volontà non funziona con stringhe di ricerca che hanno più di due parole. Ecco un'implementazione più completa in rapida. Questa soluzione consente anche di aggiungere più campi su un record, se il tuo obiettivo è quello di implementare una ricerca di testo completa attraverso nome, email, numero di telefono, ecc. In tal caso basta aggiornare NSPredicate a OR newField CONTAINS[cd] %@ e assicurarsi di aggiungere $ 0 in più l'elenco delle sostituzioni di stringhe.

let searchText = search.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) 
let words = searchText.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) 
let predicates = words.map { NSPredicate(format: "firstName CONTAINS[cd] %@ OR lastName CONTAINS[cd] %@", $0,$0) } 

let request = NSFetchRequest() 
request.predicate = NSCompoundPredicate(type: NSCompoundPredicateType.AndPredicateType, subpredicates: predicates)