Using NSPredicate with NSMutableArray - ios

I'm trying to use the input on an NSTextField along with NSPredicate to populate a NSMutableArray of like objects.
In my app I have the following simple NSMutableArray
{
firstName = Danton;
phoneNumbers = 5555555555;
}
Now, I am using the following code to try and filter the results as the user types (if "Dan" is in the textField, the filtered array should include the above object)
NSMutableArray *filteredArray = [[NSMutableArray alloc] init];
NSPredicate *sPredicate = [NSPredicate predicateWithFormat:#"firstName CONTAINS[cd] %#", self.searchField.text];
filteredArray = [[filteredArray filteredArrayUsingPredicate:sPredicate] mutableCopy];
NSLog(#"Filtered values: %#", filteredArray);
However, I am getting an empty return on filteredArray. Can someone tell me what is wrong with my code?

NSArray *array = #[
#{
#"firstName" : #"Danton", #"phoneNumbers" : #"5555555555"
}
];
NSArray *result = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"%K contains[c] %#", #"firstName", #"Dan"]];

Related

Obj-C - Filter multiple keys by text in searchbar?

I'm trying to filter two keys with the text in my search bar. See my code below so far, but it crashes my app.
NSSet *keys = [NSSet setWithObjects:#"node_title", #"address", nil];
self.filteredStores = [self.storesData filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"%K contains[c] %#", keys, self.searchBar.text]];
I feel like I'm on the right track, but I'm unable to do this successfully. Help is appreciated!
One option...
NSSet *keys = [NSSet setWithObjects:#"node_title", #"address", nil];
NSMutableArray *subpredicates = [NSMutableArray array];
for (NSString *k in keys) {
NSPredicate *p = [NSPredicate predicateWithFormat:#"%K contains[c] %#", k, self.searchBar.text];
[subpredicates addObject:p];
}
NSPredicate *final = [NSCompoundPredicate orPredicateWithSubpredicates:subpredicates];
self.filteredStores = [self.storesData filteredArrayUsingPredicate:final];

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

Searching an array for an object and checking if a NSString field matches

I have an NSMutableArray of friends that contains Parse.com PFUser objects. Each PFUser has a NSString field. I want to search this array for an object containing a specific string. So far I am using this :
NSString username = "bob";
PFUser *user = [[PFUser alloc] init];
for(PFUser *userItem in self.currentUser.friends) {
if([user.username isEqualToString:username]) {
user=userItem;
}
}
Is there a better way to do this? Is this much slower than using an NSMutable dictionary and then just pulling out the object that way? My array size is around 100. Thanks
Modify ur code as below..using NSMutableArray..only
NSString username = "bob";
PFUser *user = [[PFUser alloc] init];
for(PFUser *userItem in self.currentUser.friends) {
//In your code it is written as user.username instead of userItem.username..check it..
if([userItem.username isEqualToString:username]) {
user=userItem;
break;//exit from loop..Results in optimisation
}
}
Using Predicate..of array of objects
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", username];
NSArray *results = [self.currentUser.friends filteredArrayUsingPredicate:predicate];
PFUser *user=[[PFUser alloc]init];
user=[results objectAtIndex:0];//here is the object u need
Hope it helps you..!
Use NSPredicate, it should look something like this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.object.stringInsideObject LIKE %#", stringToCompare];
NSArray *filteredArray = [[NSArray alloc] initWithArray:[yourArray filteredArrayUsingPredicate:predicate]];
Try This,
- (PFUser *)filterUserObjectWithName:(NSString *)userName
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.username == %#",userName];
NSArray *results = [self.currentUser.friends filteredArrayUsingPredicate:predicate];
return results.count ? [results firstObject]: nil;
}
Hope this helps
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF. username contains[c] %#", stringToCompare];
NSArray *filteredArray = [[NSArray alloc] initWithArray:[yourArray filteredArrayUsingPredicate:predicate]];
Hope this will help you.

Filter array of dictionaries by NSString

while implementing search functionality I need to filter array of dictionaries. I am using auto complete textfield method for search bar and am storing it into string. I can able to parse the array,But facing with below json
[{"CertProfID":"4","Name":"Dodge","Location":"loc4","City":"city4","State":"state4","Zip":"zip5","Website":"http:\/\/cnn.com","Phone":"phone4","Email":"email4"},
{"CertProfID":"5","Name":"cat","Location":"loc5","City":"city5","State":"State5","Zip":"zip5","Website":"web5","Phone":"phone5","Email":"email5"}]
Here I need to filter the dictionaries to make it finish
I tried with below code but its returning array with null values :(
NSString *substring = [NSString stringWithString:textField.text];
NSLog(#"substring %#",substring);
NSMutableArray *arr2Filt= [arraylist valueForKey:#"Name"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",substring];
filteredarr = [NSMutableArray arrayWithArray:[arr2Filt filteredArrayUsingPredicate:predicate]];
This code will solve your problem it will return an array of dictionaries
NSString *substring = [NSString stringWithString:textField.text];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"Name contains[c] %#",searchString];
NSArray *filteredArry=[[arrayOfDict filteredArrayUsingPredicate:predicate] copy];
arrayOfDict is your original array of dictionaries
Swift 4.2 Version:::
let namePredicate = NSPredicate(format: "Name contains[c] %#",searchString)
let filteredArray = arrayOfDict.filter { namePredicate.evaluate(with: $0) }
print("names = \(filteredArray)")
Hope it will help you
You could use blocks instead. They are much less hand-wavy about match conditions.
NSString *substring = [NSString stringWithString:textField.text];
NSLog(#"substring %#",substring);
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject[#"Name"] containsString:substring];
}];
filteredarr = [NSMutableArray arrayWithArray:[arraylist filteredArrayUsingPredicate:predicate]];
Here one observation is that filteredArrayUsingPredicate is a method of NSArray and you are using NSMutableArray instead.
Change NSMutableArray with temporary NSArray object for predicate.
For example:
NSString *substring = [NSString stringWithString:textField.text];
NSArray *tempArray = [arraylist valueForKey:#"Name"];
// If [arraylist valueForKey:#"Name"]; line returns NSMutableArray than use below line
// NSArray *tempArray = [NSArray arrayWithArray:[arraylist valueForKey:#"Name"]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",substring];
filteredarr = [[tempArray filteredArrayUsingPredicate:predicate] mutableCopy];
Hi I know there is many any answer,
In my case I have stored values As JSON MODEL object, This is code for, using JSON MODEL
NSString *searchString = searchBar.text;
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
NSDictionary *temp=[evaluatedObject toDictionary];
return [temp[#"user"][#"firstName"] localizedCaseInsensitiveContainsString:searchString];
}];
filteredContentList = [NSMutableArray arrayWithArray:[searchListValue filteredArrayUsingPredicate:predicate]];
[tableViews reloadData];
searchListValue is a NSMutableArray which contains Array of json model objects.If anyone need help regarding this, just ping me
Swift version above 2.2
var customerNameDict = ["firstName":"karthi","LastName":"alagu","MiddleName":"prabhu"];
var clientNameDict = ["firstName":"Selva","LastName":"kumar","MiddleName":"m"];
var employeeNameDict = ["firstName":"karthi","LastName":"prabhu","MiddleName":"kp"];
var attributeValue = "ka";
var arrNames:Array = [customerNameDict,clientNameDict,employeeNameDict];
//var namePredicate =
// NSPredicate(format: "firstName like %#",attributeValue);
//uncomment above line to search particular word
let namePredicate =
NSPredicate(format: "firstName contains[c] %#",attributeValue);
let filteredArray = arrNames.filter { namePredicate.evaluateWithObject($0) };
print("names = ,\(filteredArray)");
More about this refer here

Filter array by first letter of string property

I have an NSArray with objects that have a name property.
I would like filter the array by name
NSString *alphabet = [agencyIndex objectAtIndex:indexPath.section];
//---get all states beginning with the letter---
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alphabet];
NSMutableArray *listSimpl = [[NSMutableArray alloc] init];
for (int i=0; i<[[Database sharedDatabase].agents count]; i++) {
Town *_town = [[Database sharedDatabase].agents objectAtIndex:i];
[listSimpl addObject:_town];
}
NSArray *states = [listSimpl filteredArrayUsingPredicate:predicate];
But I get an error - "Can't do a substring operation with something that isn't a string (lhs = <1, Arrow> rhs = A)"
How can I do this? I would like to filter the array for the first letter in name being 'A'.
Try with following code
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF like %#", yourName];
NSArray *filteredArr = [yourArray filteredArrayUsingPredicate:pred];
EDITED :
NSPredicate pattern should be:
NSPredicate *pred =[NSPredicate predicateWithFormat:#"name beginswith[c] %#", alphabet];
Here is one of the basic use of NSPredicate for filtering array .
NSMutableArray *array =
[NSMutableArray arrayWithObjects:#"Nick", #"Ben", #"Adam", #"Melissa", #"arbind", nil];
NSPredicate *sPredicate = [NSPredicate predicateWithFormat:#"SELF contains[c] 'b'"];
NSArray *beginWithB = [array filteredArrayUsingPredicate:sPredicate];
NSLog(#"beginwithB = %#",beginWithB);
NSArray offers another selector for sorting arrays:
NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(Person *first, Person *second) {
return [first.name compare:second.name];
}];
If you want to filter array take a look on this code:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name == %#", #"qwe"];
NSArray *result = [self.categoryItems filteredArrayUsingPredicate:predicate];
But if you want to sort array take a look on the following functions:
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context;
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context hint:(NSData *)hint;
- (NSArray *)sortedArrayUsingSelector:(SEL)comparator;
visit https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Collections/Articles/Arrays.html
use this
[listArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
Checkout this library
https://github.com/BadChoice/Collection
It comes with lots of easy array functions to never write a loop again
So you can just do
NSArray* result = [thArray filter:^BOOL(NSString *text) {
return [[name substr:0] isEqualToString:#"A"];
}] sort];
This gets only the texts that start with A sorted alphabetically
If you are doing it with objects:
NSArray* result = [thArray filter:^BOOL(AnObject *object) {
return [[object.name substr:0] isEqualToString:#"A"];
}] sort:#"name"];

Resources