NSPredicate contains search in a string that contains number and letters - ios

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

Related

Filter NSArray of strings when portion of string is empty using NSPredicate

I would like to filter out items of an array of strings where the right portion of a string is empty using NSPredicate but my knowledge of NSPredicate is limited.
The strings look should like {"0,General", "1,Sports", "2,Entertainment"} etc.
I want to filter out cases where you have something like: "0," or even ","
So if I had {"0,General", "1,Sports", "0,","2,Entertainment"}, I would want to filter out the flawed category "0,".
I know I can filter out entirely empty strings with something like the following:
NSArray *filteredcats = [mycats filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:#"length > 0"]];
How can I filter out strings in the array where anything to the right of a comma in the string is empty?
You can easily use regular rexpressions for this,
NSArray *myArray = #[#",First",#"0,General",#"1,Sports",#"2,Entertainment",#"3,",#","];
NSString *regex = #"^\\d,\\w+$";
NSPredicate *filter = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", regex];
NSArray *matches = [myArray filteredArrayUsingPredicate:filter];
NSLog(#"matches: %#", matches);
matches: (
"0,General",
"1,Sports",
"2,Entertainment"
)

how to find a particular string from a list of strings?

I have to get a particular string from a list of strings using NSPredicate (CoreData). For eg:
if I have the following array from CoreData
Helloworld
helloworld1234
helloworld 12345
from the above list I need only 1 and 3 one as result.
I have tried the following but i get all the three as result
NSPredicate *predicate =[NSPredicate predicateWithFormat:#"contactName CONTAINS [c]%#",[arySeperator objectAtIndex:1]];
NSArray *filteredArray1 = [arrayContacts filteredArrayUsingPredicate:predicate];
Where I am going wrong?
To find all entries that contain the given text as a "whole word", you can use the
predicate "MATCHES" operator, which matches against a regular expression, and the
word boundary pattern \b:
NSString *searchWord = #"Helloworld";
NSString *pattern = [NSString stringWithFormat:#".*\\b%#\\b.*", searchWord];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"contactName MATCHES[c] %#", pattern];
This should also work if you add this predicate to the Core Data fetch request,
instead of filtering an already fetched array of managed objects.
LIKE
The left hand expression equals the right-hand expression: ? and * are allowed as wildcard characters, where ? matches 1 character and * matches 0 or more characters.
NSString *textSearch = #"Raja";
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"firstname LIKE '*%1$#*' OR lastname LIKE '*%1$#*'", textSearch];
You can use below code to get if a string is present in an NSArray:
NSArray* yourArray = [NSArray arrayWithObjects: #"Str1", #"Str2", #"Str3", nil];
if ( [yourArray containsObject: yourStringToFind] ) {
// do found
} else {
// do not found
}

NSPredicate Creation

how shall I create an NSPredicate to that test whether a NSString start with some pattern, say "AAA"?
Thank you very much!
I tried to read Apple's reference but could not understand it.
Like this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF BEGINSWITH[cd] %#", #"AAA"];
And if you want to find all matching strings from array:
for(NSString *n in [myArray filteredArrayUsingPredicate:predicate]) {
NSLog(#"%#", n);
}
And answer to your comment about 'c' and 'd' characters etc:
SELF is in this case NSString object
BEGINSWITH[] explanation not needed, I think.
"String comparisons are by default case and diacritic sensitive. You can modify an operator using the key characters c and d within square braces to specify case and diacritic insensitivity respectively" (quote from Apple's Predicates Programming Guide)
You can try this one:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#", Your_text];

NSPredicate and BeginsWith

I would like to figure out the NSPredicate that will search my Core data for words that begins with:
For example:
description field in the core data has text like this:
My name is Mike
My name is Moe
My name is Peter
My name is George
If I search 'My name is' I need to get the 3 lines
If I search 'My name is M' I need to get the first 2 lines
I tried the code below, but can't get what I need. My guess I need a regular expression, but not sure how to do it.
[NSPredicate predicateWithFormat:#"desc beginswith [cd] %#",word];
I did it this way recently and worked fine. Try it out. I see I don't have [cd] and beginswith but contains. You could give it a try.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains %#", textField.text];
NSArray *list = [allWords filteredArrayUsingPredicate:predicate];
for(NSString *word in list){
NSLog(#"%#",word);
}
After reading the comments on the starting post:
First of all, you should split up the words in the string from the textfield:
NSArray *myWords = [textField.text componentsSeparatedByString:#" "];
Then doing the same like you first would:
for(NSString *wordFromTextField in myWords){
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains %#", wordFromTextField];
NSArray *list = [allWords filteredArrayUsingPredicate:predicate];
for(NSString *word in list){
NSLog(#"%#",word);
}
}
Instead of NSLogging the words you could add them to an array of course.

NSPredicate array contains question [duplicate]

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.

Resources