brainforked
brainforked

Reputation: 379

Compare two components by NSPredicate

I want to query an NSDictionary of contacts using NSPredicate. I am able to search the contacts using the "firstName" and "lastName" separately, but I also need to search the contacts whose complete name is entered.

For example: If I want to search a contact with name "John Doe", and I search by entering search key "John" or "Doe", I am able to get the name, but I also want it to be searchable when I enter search key "John Doe". Currently I am using :

NSPredicate *p1 = [NSPredicate predicateWithFormat:@"lastNames BEGINSWITH[cd] %@", searchText];
NSArray *p1FilteredArray = [allContacts filteredArrayUsingPredicate:p1];
NSPredicate *p2 = [NSPredicate predicateWithFormat:@"firstNames BEGINSWITH[cd] %@", searchText];
NSArray *p2FilteredArray = [allContacts filteredArrayUsingPredicate:p2];
searchedArray = [[p1FilteredArray arrayByAddingObjectsFromArray:p2FilteredArray] mutableCopy];

Upvotes: 0

Views: 98

Answers (2)

Rob
Rob

Reputation: 437482

You can use single predicate with or operator:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstNames beginswith[cd] %@ or lastNames beginswith[cd] %@", searchTerm, searchTerm];

NSArray *results = [allContacts filteredArrayUsingPredicate:predicate];

Upvotes: 1

holex
holex

Reputation: 24041

I would do something like e.g. this:

NSArray *_allContacts = // ...;
NSString *_searchText = // ...;
NSArray *_result = [_allContacts filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSDictionary * evaluatedObject, NSDictionary *bindings) {
    return ([[[evaluatedObject valueForKey:@"lastNames"] lowercaseString] hasPrefix:[_searchText lowercaseString]] || [[[evaluatedObject valueForKey:@"firstNames"] lowercaseString] hasPrefix:[_searchText lowercaseString]]);
}]];

Upvotes: 0

Related Questions