I have an array of objects with names, addresses, tel. nos, etc.
I want to be able to search the array for any occurrence of a term - whether in the name field, the address field, etc.
I have something like this in mind :
-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
// Update the filtered array based on the search text and scope.
// Remove all objects from the filtered search array
[self.searchResults removeAllObjects];
// Filter the array using NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",searchText];
searchResults = [NSMutableArray arrayWithArray:[contactArray filteredArrayUsingPredicate:predicate]];
}
This causes an exception "Can't use in/contains operator with collection".
UPDATE. I can now search on up to three fields. When I add a fourth (in any sequence), I get this exception: "Unable to parse the format string ..."
The Predicate code is now:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.narrative contains[c] %# OR SELF.category contains[c] %# OR SELF.date contains[c] OR SELF.name contains[c] %#", searchText, searchText, searchText, searchText];
searchResults = [NSMutableArray arrayWithArray:[allDreams filteredArrayUsingPredicate:predicate]];
Is three a limit of predicate search fields? How do I get around this? Thanks again.
Just use a predicate string that checks for them all:
#"name contains[cd] %# OR address contains[cd] %#"
you can add as many as you want.
The only downside is that you'll need to add the same search string for each field you want to test, which can seem a bit ugly.
If your objects are dictionaries, then there is a way to truly search all values without necessarily knowing their names at compile time, using a subquery.
It works like this:
#"subquery(self.#allValues, $av, $av contains %#).#count > 0"
It uses the #allValues special key (or method call if you prefer) for dictionary objects and uses that to filter any value that contains your search string. If any is found (i.e., the count is positive), the object is included in the results.
Notice that this will examine all values indiscriminately, even those that you don't want to include if you have any in your dictionary.
I think your array item is not pure string, right?
Suppose your array item contains name attribute (even it's a dictionary), you can search it in this way:
NSPredicate * predicate =
[NSPredicate predicateWithFormat:#"name CONTAINS[cd] %# OR name LIKE[cd] %#", searchText, searchText];
here, name can be SELF.name.
HERE's an official document.
Related
I need to filter a list of contacts, but not copy that after a certain amount of letters attached filter is damaged sample images and the NSPredicate I'm using.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"CAST(SELF.compositeName, 'NSString') contains[cd] %#",self.SearchNames.text];
Your Predicate syntax is wrong.
let predicate = NSPredicate(format: "SELF.compositeName CONTAINS[cd] %#", searchText)
let filtredArray = NSArray(array: YourContactarray.filteredArrayUsingPredicate(predicate))
When we work with array of dictionary then simply SELF.key is valid for predicate.
After this code reload your table with filtredArray which you can stored in another array for global access. Let me know if you have any problem in this code.
First thing, you have to filter the array using NSPredicate. You can follow the below link for filtering the array.
NSPredicate Example
In that link, there are many examples for filtering array using using NSPredicate.
Here array means, which is used for displaying in UITableView.
Still you have questions, please post the code with array what you have used.
Try this
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"compositeName CONTAINS[c] %#", searchText];
I have an Exit object.
Every Exit has an array of Category objects.
Objects look like this :
Category: (id, name)
Exit: (id,name,number,...,NSArray(Categories),...)
I want to use NSPredicate to filter out exits by Category name they have in Category array, but I'm not sure how exactly to write it down.
If I'd wanted to filter out Exits by Exit name, for example, I would do this
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.exitName = %#", name];
NSArray *results = [exits filteredArrayUsingPredicate:predicate];
But I'm not sure how to get into the Categories array and search by Category Name.
Any suggestions ?
Try this
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY SELF.exitName.category_name CONTAINS[c] %#", name];
NSArray *results = [exits filteredArrayUsingPredicate:predicate];
Try this predicate
NSPredicate *matchingCategory = [NSPredicate predicateWithFormat:#"SUBQUERY(categories, $c, name CONTAINS[cd] %#).#count > 0", categoryName];
Explanation
The SUBQUERY() function creates an array of objects which match the given sub-predicate. In this case, that sub-predicate is name CONTAINS[cd] %#. The way it works is by iterating over the collection (first param), assigning the name $c (second param) to refer to each element and then testing to see if the sub-predicate matches that element. If it matches, it's added to the array.
After the SUBQUERY() completes, the array is aggregated using the #count property. If there were any matches (#count > 0), the overall predicate on the exits will match the exit being tested.
My array is a collection of model object whose fields are name, address, arrTags.
Here arrTags is a NSArray.
I have to filter my array based on that arrTags values.
eg. I have values like London, Paris, Australia in arrTags.
I want to display the array index ,having London in myArray if I type letter L.
So far I have done the following:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"arrTags contains[c] %#", searchText];
arr_searchResults =[[NSMutableArray alloc] initWithArray:[myArray filteredArrayUsingPredicate:predicate]];
[image_view reloadData];
This displays the array only if I type London in my search bar.
But I want to display the array if I start typing L .
Thanks in advance.
If you want to search from inside an array (arrTaggs), you should use
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY arrTags CONTAINS[c] %#", searchText];
I have to use NSPredicatefor search through some Core Data objects. But the key nameof the custom object could contains both numbers then letters.
The string could look like:John 1234 Lennonor Ringo Starr.
I normally would use the predicate NSPredicate *predicate = [NSPredicate predicateWithFormat:#"Any name CONTAINS[cd] %#",searchString];
But, if I search for John Lennon the predicate don't return anything, because it can't compare if it contains the characters John Lennon, since is missing the 1234. Any tips what kind of predicate I can use?
You can tokenise your query , maybe as simple as
NSArray *tokens = [querystring componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
Then construct a compound predicate.
NSMutableArray *predarray = [NSMutableArray array];
for(NSString *token in tokens)
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"Any name CONTAINS[cd] %#",token];
[predarray addObject:predicate];
}
NSPredicate *final = [NSCompoundPredicate andPredicateWithSubpredicates:predarray];
And feed that to your query
In real life I would run a bit of validation against each token to check its going to make a valid predicate and wont crash or create a security risk. e.g Strip special chars like "* []"
EDIT:Corrected predicate type to work with questions situation.
Try using LIKE instead of contains, and then you can use wild cards, for instance John*Lennon should match a string that starts with John and ends with Lennon with any number of other characters in between. You can use ? Instead which would match only one character for each question mark if you want more control over what's matched.
You could split the search string up into an array of strings and then switch your predicate to look for any string in the name:
NSArray *strings = [searchString componentsSeparatedByString:#" "];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"ANY %# IN name",strings];
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Searching/Filtering a custom class array with a NSPredicate
I have a array that contains objects of a custom class, and I would like to filter the array based on if one of the classes attributes contains a custom string. I have a method that is passed the attribute that I want to be searched (column) and the string that it will search for (searchString). Here is the code I have:
NSPredicate *query = [NSPredicate predicateWithFormat:#"%# contains %#", column, searchString];
NSMutableArray *temp = [displayProviders mutableCopy];
[displayProviders release];
displayProviders = [[temp filteredArrayUsingPredicate:query] mutableCopy];
[temp release];
For some reason, this always returns an empty array. Three of the four columns are ints or doubles, so I could add an if statment to convert searchString to a number, if needed. However, even when searching the attribute that is a string, and should have some rows that contain the string searchString, an empty array is returned.
Am I using "contains" incorrectly?
For searching strings in a predicate, i've found that wrapping single quotation marks around what I am searching for works best and using contains[cd] rather than contains like below (the [cd] bit specifies a case & diacritic insensitive search):
NSPredicate *query = [NSPredicate predicateWithFormat:#"%# contains[cd] '%#'", column, searchString];
For searching a column with Integers, using double equals should work fine too:
NSPredicate *query = [NSPredicate predicateWithFormat:#"%# == %#", column, searchString];
I think your predicate should be [NSPredicate predicateWithFormat: #"column contains %#", searchString]
The way it is right now, your predicate becomes ""column" contains "string"", which always evaluates to false.
Using contains[cd] may also be a good idea depending on your situation.