NSPredicate - Return inexact matches - ios

In my app I allow users to search for vehicles by make/model using a textfield keyword search. Here is my predicate:
if (self.keywordSearch.text.length > 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"fields.make CONTAINS[cd] %# OR fields.model CONTAINS[cd] %#", self.keywordSearch.text, self.keywordSearch.text];
self.vehicleArray = [[self.vehicleArray filteredArrayUsingPredicate:predicate] mutableCopy];
}
The problem is that if the Vehicle make/model is 'Ford F-150' and the user searches F150, or F 150, the vehicle isn't included in the results. It only returns if they search F-150 or f-150.
Is there a way to make sure these inexact matches are returning?

I suggest using regular expressions for this. You can either use a regular expression literal inside the NSPredicate format (described here: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Predicates/Articles/pUsing.html ) or you can iterate the array manually and use an NSRegularExpression for comparing the strings.

Related

How to set predicate for a string attribute holding integer value in core data

How to set predicate for a string attribute holding integer value in core data to get the in-between values in integer.
I am using compound predicate for multiple conditions and a piece of code follows..
NSPredicate *categoryPredicate = [NSPredicate predicateWithFormat: #"rating >= %# AND rating <= %#",ratingFrom.text,ratingTo.text];
[compoundPredicateArray addObject: categoryPredicate ];
"rating" attribute is of type string in database. I need to get the rating between the given range in the ratingFrom & ratingTo textfields.
"1" to "10" should fetch all ratings in between 1 to 10.how can I achieve this, without changing the attribute type to number.
Any help appreciated..Thanks
i am not confirm but try this
convert your values in NSString and put this code
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"string CONTAINS[c] %#",searchText];
Ideally you should change this attribute to be a number rather than a string. But if that's not possible, the following should force CoreData (or rather SQLite) to treat it as a number:
NSPredicate *categoryPredicate = [NSPredicate predicateWithFormat: #"add:to:(rating,0) >= %d AND add:to:(rating,0) <= %d",ratingFrom.text.intValue,ratingTo.text.intValue];
you can try BETWEEN expression:
BETWEEN The left-hand expression is between, or equal to either of,
the values specified in the right-hand side. The right-hand side is a
two value array (an array is required to specify order) giving upper
and lower bounds. For example, 1 BETWEEN { 0 , 33 }, or $INPUT BETWEEN
{ $LOWER, $UPPER }. In Objective-C, you could create a BETWEEN
predicate as shown in the following example:
So your code should look like this:
NSPredicate *betweenPredicate =
[NSPredicate predicateWithFormat: #"rating BETWEEN %#", #[ratingFrom, ratingTo]];
ratingFrom, ratingTo should be NSNumber instances if rating is NSNumber.

how to create a predicate in which % work as a string in ios

I am using a Predicate for filtering a NSArray but, when a create Predicate like this
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K contains[c] %# && %K contains[c] %# ",
kUnitUnitcategoryKey,
#"Blood Pressure Diastolic",
kUnitUnitNameKey,
[_txtOxygenSaturationUnit.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
after this "predicate" string is : "unit_category CONTAINS[c] "Blood Pressure Diastolic" AND unit_name CONTAINS[c] "%" "
NSArray *results = [_arrUnitsName filteredArrayUsingPredicate:predicate];
it will return Zero records.
Now, how can i used % as a string.
This is an extremely ugly way to write a somewhat complex predicate. You'll find using NSCompoundPredicates are MUCH easier to manage and modify. Simply create your multiple NSPredicates then use an andPredicate to combine all of your predicates.
What is the best way to build a complex NSCompoundPredicate?
As far as the actual question of how can you use % as a string? Test each predicate individually if you are getting zero results for easier debugging and you'll find the issue much easier.

iOS: NSPredicate doesn't work correct

I try to express the search parameters with predicate:
NSPredicate *predicate=[NSPredicate predicateWithFormat:#"name CONTAINS [cd] %# OR code CONTAINS [cd] %# OR currency CONTAINS [cd] %# AND continent.paid == %#",searchString,searchString,searchString,[NSNumber numberWithBool:YES]];
I try to express search parameters for possible string records ONLY where continent.paid==YES. The problem is that last expression is ignored. The search returns data from continent.paid==NO as well with the correct data. Whats wrong with it?
You have to set parentheses:
[NSPredicate predicateWithFormat:#"(name CONTAINS [cd] %# OR code CONTAINS [cd] %# OR currency CONTAINS [cd] %#) AND continent.paid == %#",
searchString,searchString,searchString,[NSNumber numberWithBool:YES]];
As far as I know, "AND" and "OR" have the same precedence in a predicate, and are evaluated
from left to right. Therefore in your code, the predicate evaluates to true if one
of the "CONTAINS" expressions is true.

How can I filter UITableView with two predicates in IOS

I have tableView with searchDisplayController. In this TV i have to arrays (first/last names)
I can filter this values by names, using predicate, with this code
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self.firstName beginswith[cd]%#",searchString];
self.filteredAllClients = [AllClients filteredArrayUsingPredicate:predicate];
Can i filter this arrays using two predicates?
For example: I have names (Jack Stone, Mike Rango)
If I`m entering 'J' and i should get filtered array - Jack Stone
But if I'm entering 'R' and i should get filtered area - Mike Rango?
Yes, like this...
NSPredicate *firstNamePredicate = [NSPredicate predicateWithFormat:#"self.firstName beginswith[cd]%#",searchString];
NSPredicate *lastNamePredicate = [NSPredicate predicateWithFormat:#"self.lastName beginswith[cd]%#",searchString];
NSPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:#[firstNamePredicate, lastNamePredicate]];
self.filteredAllClients = [AllClients filteredArrayUsingPredicate:compoundPredciate];
This will then show all people whose first names begin with the search OR whose last names begin with the search.
I prefer using this format to using the ORs and ANDs in a single predicate as it makes the overall code more readable.
This can also be used to get the NOT of a predicate.
You can also easily get confused if you have compound predicates built in a single predicate.

NSPredicate for Regular Search

I am using NSPredicate for the performing Search as it does on iPhone when we search for any app.
I have say for example 4 keywords
Deccan
New Delhi
Ahmedabad
Salaam Delhi
I have tried creating a predicate with
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"keyword BEGINSWITH[c] 'd'"
It gives me Deccan as output.
But the problem is I want each word starting with d So from the above example I need output as
Deccan, New Delhi, Salaam Delhi but NOT Ahmedabad
Stucked in this issue from hours. tried contains, matches but my bad luck..
Any help towards right path will really be appreciated..
Thanks guys for your responses
Here's what I come up with
NSString *matchString = [NSString stringWithFormat: #".*\\b%#.*",searchText];
NSString *predicateString = #"keyword MATCHES[c] %#";
NSPredicate *predicate =[NSPredicate predicateWithFormat: predicateString, matchString];
There are two way for you
Divide the steing by ' ' and use your NSPredicate *predicate = [NSPredicate predicateWithFormat:#"keyword BEGINSWITH[c] 'd'"]
Or, the better way, to use two predicates :
predicate = [NSPredicate predicateWithFormat:#"keyword BEGINSWITH[c] 'd'
OR keyword contains[c] ' d'"]// i mean,'space+d'
So you'll it will satisfy both of possible cases.
Consider "like" and "matches." Note, however, that these are relatively expensive operations, and can take considerable time on large data sets.
In this example, I assume what you want is to match if any space-separated word in starts with "d"
This checks to see if keyword either begins with 'd' or has a sequence with a followed by 'd'
[NSPredicate predicateWithFormat:#"(keyword BEGINSWITH[c] 'd') OR (keyword LIKE[c] '* d')"]
This one uses a regular expression, which is very similar (use the regex that best suites your situation:
[NSPredicate predicateWithFormat:#"keyword MATCHES[c] '^d.*|.*\\sd.*'"]

Resources