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"
Related
I need to sort search results by relevance, while attempting to work around Realm's NSPredicate limitations.
My current attempt duplicates results:
if searchText.characters.count > 0 {
//First search is attempting exact match
relevantResults = Array(dataModel.terms.filter("%K BEGINSWITH[c] %#", "title", searchText).sorted(byProperty: "title"))
//Appended Results are looking for 'close enough' but include results that were already in the first search
relevantResults.append(contentsOf: Array(dataModel.terms.filter("%K CONTAINS[c] %#", "title", searchText).sorted(byProperty: "title")))
} else {
relevantResults = Array()
}
I've tried to get creative with some other predicate filters such as:
"title NOT BEGINSWITH[c] %# AND title CONTAINS[c] %#"
and
"SELF NOT IN %#"
Which are either not supported by Realm, or not valid predicate filters.
Either way I need to find a solution to sort by relevance without duplicates.
There will be more search results shown in a separate TableView Section, that I would like to exclude the "best match" results as well.
I want to avoid looping to get all the titles from the first set of results if possible, but it seems like I may have to resort to that, unless there are some array functions that I'm not considering? Any suggestions?
Apparently my predicate string was a little off.
"title CONTAINS[c] %# AND NOT title BEGINSWITH[c] %#"
ended up working for me.
I am trying to search in CoreData for an object that matches both a recordId and a string name, but it doesn't always find the object.
For example, I an searching for an object with id 1000 and name "The Brown Family" (note the 2 spaces between "The" and "Brown").
If I use:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(recordId == %#") AND (name like[cd] %#)", recordId, name];
with recordId=1000 and name="The Brown Family", the fetch request returns nil.
If I use:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(recordId == %#"), recordId];
with recordId=1000, it finds the object. If I print the object's name property, I get "The Brown Family".
So the object is there with the correct id and name, but my fetchRequest fails.
What am I doing wrong?
You might need to enclose the value in single quotes...
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(recordId == %#) AND (name like[cd] '%#')", recordId, name];
Sorry but I realise what the problem is now! The name I was searching for had a trailing space after it. So I was looking for say "Toby " whereas "Toby" was stored in Coredata.
Sorry for wasting everyone's time.
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 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 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.*'"]