What I do:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"SELF.street contains[c] %# OR SELF.id contains[c] %#", searchText];
self.filteredItems = [NSMutableArray arrayWithArray:
[self.items filteredArrayUsingPredicate:predicate]];
I want to check if the given searchText is either in ID or in STREET property. STREET alone works, however as soon as I add the ID check my app crashes.
Any idea how to have both checks for ID and STREET ind the predicate?
You're using %# twice, but only providing one argument, try:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"SELF.street contains[c] %# OR SELF.id contains[c] %#", searchText, searchText];
I changed ID from NSNumber to NSString. Now it works.
Related
For example, I have object like #{#"firstName":#"aaa", #"lastName":#"bbb"}.
Now I'm trying to search with next predicate:
NSPredicate *predicateFirstName = [NSPredicate predicateWithFormat:#"firstName contains [c] %#", searchString];
NSPredicate *predicateLastName = [NSPredicate predicateWithFormat:#"lastName contains [c] %#", searchString];
NSPredicate *orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:#[predicateFirstName, predicateLastName]];
searchUsersArray = [usersArray filteredArrayUsingPredicate:orPredicate];
I need a predicate, which will be return for search string #"aa bb" users whose first name ENDED with "aa" and lastName BEGINS with #"bb"
NSPredicate *predicateLastName = [NSPredicate predicateWithFormat:#"(firstName AND lastName contains [c] %#)", searchString]
don't work for me.
First divide the search string in the end-part and the begin-part:
NSArray *parts = [#"aa bb" componentsSeperatedByString:#" "];
Then use BEGINSWITH and ENDSWITH:
[NSPredicate predicateWithFormat:#"(firstName ENDSWITH[c] %#) AND (lastName BEGINSWITH[c] %#", parts[0], parts[1]];
Alternatively you can add a computed property to the entity concatinating the first name and last name and then search in this property.
Try like this hope it help you
NSString *matchString = [NSString stringWithFormat: #"(.*aa|bb.*)",searchText];
NSString *predicateString = #"keyword MATCHES[c] %#";
NSPredicate *predicate =[NSPredicate predicateWithFormat: predicateString, matchString];
Thanks
Use keyword BEGINSWITH instead of contains.
NSPredicate *predicateFirstName = [NSPredicate predicateWithFormat:#"firstName BEGINSWITH [c] %#", searchString];
NSPredicate *predicateLastName = [NSPredicate predicateWithFormat:#"lastName BEGINSWITH [c] %#", searchString];
Right now, I have a working app (similar to WhatsApp) where users can do a live search using an NSTextField to add users to a group chat. Using NSPredicate, I search through an array (searchableContacts) to find any available contacts on the app, and like matches are output to a UITableView, like so:
- (void)textFieldDidChange :(UITextField *)theTextField {
[filteredArray removeAllObjects];
NSMutableArray *partPredicates = [NSMutableArray arrayWithCapacity:2];
NSPredicate *currentPartPredicate1 = [NSPredicate predicateWithFormat:#"firstName CONTAINS[cd] %#", self.searchField.text];
NSPredicate *currentPartPredicate2 = [NSPredicate predicateWithFormat:#"lastName CONTAINS[cd] %#", self.searchField.text];
[partPredicates addObject:currentPartPredicate1];
[partPredicates addObject:currentPartPredicate2];
NSPredicate *fullPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:partPredicates];
filteredArray = [[self.searchableContacts filteredArrayUsingPredicate:fullPredicate] mutableCopy];
[self.searchableMembers reloadData];
}
On the resulting tableView, users are able to select users to add to the group. Now, I have an 'addedContacts' array.
When the user goes back into the textField to search for more users to add to the group, how can I alter my NSPredicate to include available contacts (from searchableContacts) that are not already in the group (addedContacts)?
You can simplify the code you have for building the predicate to this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"firstName CONTAINS[cd] %# OR lastName CONTAINS[cd] %#", self.searchField.text, self.searchField.text];
You can adjust that to exclude the items in addedContacts using this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(NOT SELF IN %#) AND (firstName CONTAINS[cd] %# OR lastName CONTAINS[cd] %#)", self.addedContacts, self.searchField.text, self.searchField.text];
I have an array of objects with name and address.
Both properties are of type NSString.
But when i'm using the compound predicate with both results i don't get any result. If i'm using just one predicate it works very well.
Has anyone an idea whats going wrong here in my code? thnx
-(void)filterContentForSearchString:(NSString*) searchText
{
NSPredicate *resultsPredicate = [NSPredicate predicateWithFormat:#"SELF.name like[cd] %#", searchText];
NSPredicate *resultsPredicate2 = [NSPredicate predicateWithFormat:#"SELF.place like[cd] %#", searchText];
NSPredicate *compoundpred = [NSCompoundPredicate andPredicateWithSubpredicates:#[resultsPredicate, resultsPredicate2]];
self.searchResults = [self.companies filteredArrayUsingPredicate:compoundpred];
}
Can you try using a single predicate declaration
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"SELF.name like[cd] %# OR SELF.place like[cd] %#", searchText, searchText];
and filter the array with it directly
self.searchResults = [self.companies filteredArrayUsingPredicate:predicate];
i'm using a NSPredicate to filter an array in my searchbar. This is my code which works perfectly.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.name contains[cd] %#",searchText];
filteredArray = [NSMutableArray arrayWithArray:[storesArray filteredArrayUsingPredicate:predicate]];
The problem is i want to add a second condition as the name which is the address. How can i do this? I've tried this, but then none of the predicates are working.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.name contains[cd] %#",searchText];
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:#"SELF.address contains[cd] %#",searchText];
NSPredicate *fullPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:#[predicate, predicate1]];
filteredArray = [NSMutableArray arrayWithArray:[storesArray filteredArrayUsingPredicate:fullPredicate]];
You can use the OR comparison operator:
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"SELF.name contains[cd] %# OR SELF.address contains[cd] %#", searchText, searchText];
[filteredArray filterUsingPredicate:
[NSPredicate predicateWithFormat:#"self BEGINSWITH[cd] %#", searchText]];
filteredArray contains simple NSStrings. [hello, my, get, up, seven, etc...];
It will give all strings that begin with searchText.
But if string will be a combination of words like "my name is", and searchText = name. What would a NSPredicate look like to achieve this?
UPDATE:
And how would it have to be if i want to a result with searchText = name, but not with searchText = ame? Maybe like this:
[filteredArray filterUsingPredicate:
[NSPredicate predicateWithFormat:
#"self BEGINSWITH[cd] %# or self CONTENTS[cd] %#",
searchText, searchText]];
But it should first display the strings that begin with searchText and only after those which contain searchText.
[NSPredicate predicateWithFormat:#"self CONTAINS[cd] %#", searchText];
EDIT after expansion of question
NSArray *beginMatch = [filteredArray filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:
#"self BEGINSWITH[cd] %#", searchText]];
NSArray *anyMatch = [filteredArray filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:
#"self CONTAINS[cd] %#", searchText]];
NSMutableArray *allResults = [NSMutableArray arrayWithArray:beginMatch];
for (id obj in anyMatch) {
if (![allResults containsObject:obj]) {
[allResults addObject:obj];
}
}
filteredArray = allResults;
This will have the results in the desired order without duplicate entries.
EDIT Actually beginsWith check from start of string to search string length. if exact match found then its filtered
if u have name game tame lame
search Text : ame
filtered text would be: none
contains also check from start of string to search string length but if found start, middle or end exact search string then it is filtered.
if u have name game tame lame
search Text : ame
filtered text would be: name game tame lame because all has ame
[NSPredicate predicateWithFormat:#"self CONTAINS '%#'", searchText];