2012-11-20 13 views
8

Mam zestaw użytkowników w CoreData i pole wyszukiwania w mojej aplikacji. Użytkownik ma właściwości imię i nazwisko.NSPredicate: Połącz CONTAINS z IN

Obecnie mam predykat jak „user.name ZAWIERA [c]% @ LUB user.firstname ZAWIERA [c]% @”

Działa to aż użytkownik wpisze pełnej nazwy jak „Jan Kowalski”. Nawet jeśli wpisuje "john sm", należy znaleźć obiekt Johna Smitha.

Co to jest predykat do połączenia tablicy (IN) wyszukiwanych haseł z CONTAINS?

Odpowiedz

13

2,5 roku później mogę odpowiedzieć na moje pytanie o BI t bardziej złożony przykład 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

Niesamowity człowiek. Wielkie dzięki! –

+6

Jest to prawdopodobnie to samo, co odpowiedź @Martin R. Różnica w języku. Powinieneś go przyjąć. – Eddie

35

Nie sądzę, że można połączyć "IN" z "CONTAINS" w predykacie. Ale można podzielić ciąg wyszukiwania w słowach, i stworzyć „związek predykat”:

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); 

Ten przykład produkuje orzecznika

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

który pasowałby do „John Smith”, ale nie „John Miller ".

+2

5 lat w iOS i po raz pierwszy zobaczyłem to. To powinno być nadal akceptowaną odpowiedzią. –

0

miałem ten sam problem i rozwiązać go tak:

W mojej klasie NSManagedObject (użytkownika) Dodałem następującą metodę, łącząc dwie wartości w jednym ciągiem:

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

wtedy „ll trzeba tylko następujące wiersze do meczu z listy, która jest w moim przypadku, gdy NSArray z obiektów użytkowników:

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

to nie rozwiązuje problemu, gdy użytkownik wyszukuje hasło "nazwisko" – 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] 

pomocą orCompoundPredicate podczas pobierania danych.