Plist NSPredicate in iOS - ios

I have a plist working with a search display controller which contains an array of dictionaries with some data members like.
<root> (array)
<"Item 0"> (dictionary)
<"Name"></"Name" (String)
<"Work"></"Work"> (String)
<"Age"></"Work"> (Number)
</"Item 0">
<"Item 1">
....
</"Item 1">
</root>
I would like to use an NSPredicate to filter all the names that match with the search criteria. For example searching "an" for all names will yield "Sandy" and "Alexander."
So far I've tried things like:
NSPredicate *p = [NSPredicate predicateWithFormat:#"Name == %#",
filterText];
Results = [data filteredArrayUsingPredicate:p];
Any ideas? Thanks.

Use CONTAINS in NSPredicate
Below code gives case sensitive search
NSPredicate *p = [NSPredicate predicateWithFormat:#"Name CONTAINS %#",
filterText];
Results = [yourPlistDataArray filteredArrayUsingPredicate:p];
Below code gives case insensitive search
NSPredicate *p = [NSPredicate predicateWithFormat:#"ANY Name CONTAINS %#",
filterText];
Results = [yourPlistDataArray filteredArrayUsingPredicate:p];
EDIT : Refer more here

this can show you the very generic type of the searching in any NSArray. it is adjusted to your NSDictionary items currently, but you can create even more complex conditions here to filter it.
NSArray *originalArray = ...;
NSString *searchText = ...; // this is a parameter only, it can be set freely
NSArray *_filteredArray = [originalArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
NSDictionary *_dataRow = (NSDictionary *)evaluatedObject;
return ([[[_dataRow valueForKey:#"Name"] lowercaseString] rangeOfString:[searchText lowercaseString]].location != NSNotFound);
}]];
NSLog (#"%#", _filteredArray);

Related

Obj-c - Filter array to return dictionaries in which a key contains values listed in NSMutableArray?

I have an array (allFriends) which returns a number of dictionaries (data for about 50 people). Each dictionary contains the key 'uid'. I want to filter allFriends so that all dictionaries in which uid contains the numbers 1,2,3, or 4 are returned.
How might I accomplish this? The numbers I want to filter with are returned in an array, and are grabbed like so:
NSMutableArray *friendUIDs = [self.friendData valueForKey:#"uid"];
This returns the data as: "1, 2, 3, 4"
No matter what I try however (thought NSPredicate would be the way to go), my code doesn't seem to want to let me filter with multiple values separated by a comma?
NSArray *filteredData = [self.allFriends filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(uid contains[c] %#)", friendUIDs]];
Hope I worded this correctly.
Your final predicate should look something like this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.uid contains[c] %# OR SELF.uid contains[c] %#", #"1",#"2"];
If I understand the question correctly, this should work:
NSMutableArray *friendUIDs = [self.friendData valueForKey:#"uid"];
NSMutableString *predicateString = [NSMutableString string];
for (NSInteger i = 0; i < [friendUIDs count]; i++) {
if (i != 0) {
[predicateString appendString:#" OR "];
}
[predicateString appendFormat:#"SELF.uid contains[c] '%1$#'", friendUIDs[i]];
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
NSArray *filteredData = [allFriends filteredArrayUsingPredicate:predicate];

Filter Array of custom objects using NSPredicate in Objective C

I have one array which contains dictionary of custom objects.I want to filter that array for search functionality in UITableView. Here is my code for single object Filtration using NSPredicate.
self.searchResultForName = [self.multiPracticeDetailsArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
ObjectHolder *obj = (ObjectHolder*)evaluatedObject;
return [obj.Name hasPrefix:searchText];
}]];
Using above code, I can search only for Name , but i want to search for both By Name and ID.Also search will be case insensitive. How can i do this in Objective-C?.Please Suggest any better way to do this.
Did you tried with || OR operator & lowercaseString.
self.searchResultForName = [self.multiPracticeDetailsArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
ObjectHolder *obj = (ObjectHolder*)evaluatedObject;
return [[obj.Name lowercaseString] hasPrefix:[searchText lowercaseString]] || [[obj.ID lowercaseString] hasPrefix:[searchText lowercaseString]] ;
}]];
You can try filtering it like this, assuming your ObjectId property is NSInteger:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"Name =[c] %# OR ObjectId =[c] %ld", searchText, searchId];
NSArray *filteredArray = [self.multiPracticeDetailsArray filteredArrayUsingPredicate:predicate];

NSPredicate to compare identical string arrays?

Is it possible to use nspredicate to compare whether one NSArray is exactly equal to another NSArray of strings? I need this dome via predicates because of its possible I will add this predicate to a compound predicate.
The Array I am comparing against is a property of an NSDictionary.
So the answer was a mixture of both, I did use the predicatewithformat but got creative in the string inside, inspired by #akashivskyy and #avi
[predicatesArray addObject:[NSPredicate predicateWithFormat:#"ANY dynamic.values == %#", arr]];
Edit: As (partially) suggested by Avi, you may use the equality predicate:
NSArray *otherArray = #[ #"foo", #"bar" ];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self == %#", otherArray];
[predicate evaluateWithObject:#[ #"foo", #"bar" ]]; // YES
[predicate evaluateWithObject:#[ #"baz", #"qux" ]]; // NO
Alternatively, and if you have any trouble with format string in the future, you may always use a block predicate to perform your own logic:
NSArray *otherArray = #[ #"foo", #"bar" ];
NSPredicate *predicate = [NSPredicate predicateWithBlock:^(NSArray *evaluatedArray, NSDictionary<NSString *, id> *bindings) {
return [evaluatedArray isEqualToArray:otherArray];
}];
// use the predicate

Using predicate to find if string value exists

I have a NSMutableArray of objects with tag attributes assigned to them. I am trying to find if any of these objects have a tag assigned to them of the string value "a".
my code so far:
for (Object *object in self.array)
{
NSDictionary *attrs = [object propertyValue:#"attrs"];
NSString *tag = attrs[#"tag"];
}
Can I do something like:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"a"];
NSArray *results = [self.array filteredArrayUsingPredicate:predicate];
not sure how it works?
Try this
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"tag == %#", #"a"];
NSArray *result = [NSMutableArray arrayWithArray:[self.array filteredArrayUsingPredicate:predicate]];
Use 'contains[c]' instead of '==' if you want to perform case-insensitive search.
If you want to filter for any other property, replace 'tag' with that property name.
You will need to do something more like :
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.property_name contains[c] '%#'", #"a"];
NSArray *result = [NSMutableArray arrayWithArray:[self.array filteredArrayUsingPredicate:predicate]];

How to perform search on array if it has items matching then copy those items in another array in ipad app

I have a app in which i want searching. I have a array resultArray which contain all the things which display like
Book*bookObj=[resultArray objectAtIndex.indexPath.row];
NSString*test=bookObj.title;
I want to perform search on title item in resultArray if search text enter in textfield matches with title with any of the arrays then copy those all array values in testArray.
Use this as :
NSMutableArray *searchDataMA = [NSMutableArray new];
for (int i = 0; i < resultArray.count; i++) {
Book *bookObj=[resultArray objectAtIndex:i];
NSString*test=bookObj.title;
NSRange rangeValue1 = [test rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (rangeValue1.length != 0) {
if (![resultArray containsObject:test]) {
[searchDataMA addObject:test];
}
}
}
You have to take another array for this. this will add your object
for (Book * bookObj in resultArray) {
NSString *strName=[[bookObj.title]lowercaseString];
if ([strName rangeOfString:searchText].location !=NSNotFound) {
[arrTemp addObject:bookObj];
}
}
- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate is exactly the function that you want. It will return a new array with only the elements that pass the test in the NSPredicate object.
For example:
NSArray *newArray = [oldArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(Book *evaluatedObject, NSDictionary *bindings) {
//Do whatever logic you want to in here
return [evaluatedObject.title isEqualToString:theTitle];
}];
It works for me try this:
NSArray *fruits = [NSArray arrayWithObjects:#"Apple", #"Crabapple", #"Watermelon", #"Lemon", #"Raspberry", #"Rockmelon", #"Orange", #"Lime", #"Grape", #"Kiwifruit", #"Bitter Orange", #"Manderin", nil];
NSPredicate *findMelons = [NSPredicate predicateWithFormat:#"SELF contains[cd] 'melon'"];
NSArray *melons = [fruits filteredArrayUsingPredicate:findMelons];
NSPredicate *findApple = [NSPredicate predicateWithFormat:#"SELF beginswith 'Apple'"];
NSArray *apples = [fruits filteredArrayUsingPredicate:findApple];
NSPredicate *findRNotMelons = [NSPredicate predicateWithFormat:#"SELF beginswith 'R' AND NOT SELF contains[cd] 'melon'"];
NSArray *rNotMelons = [fruits filteredArrayUsingPredicate:findRNotMelons];
NSLog(#"Fruits: %#", fruits);
NSLog(#"Melons: %#", melons);
NSLog(#"Apples: %#", apples);
NSLog(#"RNotMelons: %#", rNotMelons);
Predicates also have more condition functions, some of which I have only touched on here:
beginswith : matches anything that begins with the supplied condition
contains : matches anything that contains the supplied condition
endswith : the opposite of begins with
like : the wildcard condition, similar to its SQL counterpart. Matches anything that fits the wildcard condition
matches : a regular expression matching condition. Beware: quite intense to run
The syntax also contains the following other function, predicates and operations:
AND (&&), OR (||), NOT (!)
ANY, ALL, NONE, IN
FALSE, TRUE, NULL, SELF
Still if don't understand take a look at this link;
Useful link

Resources