Using NSPredicate to search a 2D array - ios

I want to use NSPredicate to search for a similar/matching string in an array of an array and return the array that contains the string.
Below is an example of the 2D array that I am wanting searched.
NSMutableArray *people [
[#"Jane", #"Doe"],
[#"John", #"Smith"]
]
Example: Searching "Jane" will return the array [#"Jane", #"Doe"]
Note: The inner arrays are NSMutableArray's, NOT NSArray's.
I tried using this code:
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#", searchText];
searchResults = [people filteredArrayUsingPredicate:resultPredicate];
but no results are shown no matter what I type and an alert that tells me the count of searchResults reports 0.

Related

Filter NSArray of Arrays by One Element of Array Using NSPredicate in IOS

It is possible to filter an array of strings as follows:
NSArray *array = #[#"honda",#"toyota",#"ford"];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#",#"ford"];
NSArray *filtered = [array filteredArrayUsingPredicate:pred];
I want to search an array that contains arrays of two strings by the values for the first of the strings. So for:
NSArray *cars = #[#[#"honda",#"accord"],#[#"toyota",#"corolla"],#[#"ford",#"explorer"]];
I want to search the first dimension (honda, toyota, ford) for #"ford"
Is there a way to tell the predicate I want to search on only the first attribute and return matching elements of the array?
Well here is the pred you need.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF[FIRST] contains[cd] %#", #"ford"];

Filtering array of data where the filter text is array of strings using NSPredicate

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

NSPredicate on an NSArray to search for any object

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.

NSPredicate Contains with List

I have a list of tags like item 1, item 2 and I want to use an NSPredicate to filter an array if a field matches anything in those items. This doesn't accomplish it:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY tags CONTAINS[c] %#", tag];
results = [results filteredArrayUsingPredicate:predicate];
Use the IN operator followed by the array of tags.
predicate = [NSPredicate predicateWithFormat:#"ANY tags IN %#", theTags];

How to filter array with NSPredicate for combination of words

[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];

Resources