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.*'"]
Related
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.
I need some help to figure out the correct NSPredicate syntax to correctly search my array that is like:
CSVFinalData: (
"Width:1,5 Diameter:12 Strength:0,25 Strength:900 Mode:L Spring:371M ",
"Width:2,2 Diameter:6,5 Strength:0,45 Strength:1200 Mode:M Spring:485M ",
"Width:3,5 Diameter:14,5 Strength:0,3 Strength:1600 Mode:M Spring:380M ",
"Width:5 Diameter:7 Strength:0,25 Strength:850 Mode:L Spring:525M ",
"Width:4,2 Diameter:10,2 Strength:0,4 Strength:1200 Mode:S Spring:1232S ",
"Width:3 Diameter:6,8 Strength:0,15 Strength:800 Mode:S Spring:1439S ",
"Width:1 Diameter:4,7 Strength:0,12 Strength:450 Mode:L Spring:129M ",
"Width:7,3 Diameter:15,5 Strength:0,5 Strength:1400 Mode:M Spring:563M "
)
This is my NSPredicate:
NSPredicate *csvsearch =
[NSPredicate predicateWithFormat:#"'Width:' MATCHES %#", searchBar.text];
I also tried some other predicates but the result is empty on every time.
The only exception is when searchBar.text is 'Width:' it will show every object.
I am using Xcode 6.1 and iOS 8.1.
Thanks for your help!
#edit:
I played around a bit with #Larme solution. CONTAINS is too imprecise. When searching for a Width of 4,2 it will also find rows with Diameter 4,2. This should be theoretically correct:
[NSPredicate predicateWithFormat:#"self CONTAINS 'Width:4,2'"];
to make it dynamic I changed it to:
[NSPredicate predicateWithFormat:#"self CONTAINS '%#:%#'", csvHeaderName1, searchBar.text];
But once it is dynamic it won't work anymore but I don't get why :(
csvHeaderName1 hast the content "Width" and searchBar.text "4,2"
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.
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.
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.