2012-11-20 13 views
8

Ich habe eine Reihe von Benutzern in CoreData und ein Suchfeld in meiner Anwendung. Der Benutzer hat die Eigenschaften Vorname und Name.NSPredicate: Kombiniere CONTAINS mit IN

Zur Zeit habe ich ein Prädikat wie "user.name ENTHÄLT [c]% @ OR user.firstname ENTHÄLT [c]% @"

Das funktioniert, bis der Benutzer einen vollständigen Namen wie "John Smith". Auch wenn er "john sm" eintippt, sollte das John Smith-Objekt gefunden werden.

Was ist das Prädikat, um ein Array (IN) von Suchbegriffen mit CONTAINS zu kombinieren?

Antwort

13

2,5 Jahre später kann ich meine Frage mit einem bi beantworten t komplexeres Beispiel in SWIFT:

var predicateList = [NSPredicate]() 

let words = filterText.componentsSeparatedByString(" ") 

for word in words{ 

    if count(word)==0{ 
      continue 
    } 

    let firstNamePredicate = NSPredicate(format: "firstName contains[c] %@", word) 
    let lastNamePredicate = NSPredicate(format: "lastName contains[c] %@", word) 
    let departmentPredicate = NSPredicate(format: "department contains[c] %@", word) 
    let jobTitlePredicate = NSPredicate(format: "jobTitle contains[c] %@", word) 

    let orCompoundPredicate = NSCompoundPredicate(type: NSCompoundPredicateType.OrPredicateType, subpredicates: [firstNamePredicate, lastNamePredicate,departmentPredicate,jobTitlePredicate]) 

    predicateList.append(orCompoundPredicate) 
} 

request.predicate = NSCompoundPredicate(type: NSCompoundPredicateType.AndPredicateType, subpredicates: predicateList) 
+0

Amazing man. Danke vielmals! –

+6

Dies ist wahrscheinlich das gleiche wie @Martin R's Antwort, nur Unterschiede in der Sprache. Du solltest ihn imo akzeptieren. – Eddie

35

Ich glaube nicht, dass Sie "IN" mit "CONTAINS" in einem Prädikat kombinieren können. Aber man konnte die Suchzeichenfolge in Wörter aufgeteilt, und erstellen Sie eine „Verbindung Prädikat“:

NSString *searchString = @"John Sm "; 
NSArray *words = [searchString componentsSeparatedByString:@" "]; 
NSMutableArray *predicateList = [NSMutableArray array]; 
for (NSString *word in words) { 
    if ([word length] > 0) { 
     NSPredicate *pred = [NSPredicate predicateWithFormat:@"user.name CONTAINS[c] %@ OR user.firstname CONTAINS[c] %@", word, word]; 
     [predicateList addObject:pred]; 
    } 
} 
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicateList]; 
NSLog(@"%@", predicate); 

Dieses Beispiel erzeugt das Prädikat

(user.name CONTAINS[c] "John" OR user.firstname CONTAINS[c] "John") AND 
(user.name CONTAINS[c] "Sm" OR user.firstname CONTAINS[c] "Sm") 

was passen würde „John Smith“, aber nicht „John Miller ".

+2

5 Jahre in iOS, und dies ist das erste Mal, dass ich das gesehen habe. Dies sollte immer noch die akzeptierte Antwort sein. –

0

hatte ich das gleiche Problem und löste es dies wie:

In meiner NSManagedObject Klasse (Benutzer) Ich habe die folgende Methode, die beiden Werte in einer einzigen Zeichenfolge Fusion:

- (NSString *)name 
{ 
    return [NSString stringWithFormat:@"%@ %@", self.firstname, self.lastname]; 
} 

Sie dann finden Sie die folgenden Zeilen müssen nur gegen Ihre Liste übereinstimmen, die in meinem Fall ist ein NSArray mit Benutzerobjekte:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchString]; 
NSArray *filteredUsers = [users filteredArrayUsingPredicate:predicate]; 
+0

das löst das Problem nicht, wenn Benutzer nach "Nachname Vorname" sucht – netshark1000

0

Swift 4 Update:

let firstName = NSPredicate(format: "firstName CONTAINS[c] %@", searchText) 
let lastName = NSPredicate(format: "lastName CONTAINS[c] %@", searchText) 

let orCompoundPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: 
[firstNamePredicate,lastNamePredicate] 

Verwenden der orCompoundPredicate während Daten abgerufen werden.