Reputation: 16841
I have several problems relating to NSPredicates, here are they;
1.) My code is as follows;
NSArray *arr= [self.humanArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"ANY name IN %@ ", nameArray]];
I get the following exception;
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'The left hand side for an ALL or ANY operator must be either an NSArray or an NSSet.'
*** Call stack at first throw:
When i write the predicate as @"name IN %@ ", nameArray
. It works, but i think there might be some underneath flaw in this.
note: the humanArray
, contains objects of HUMAN
, and an object of human
contains the following attributes. name
, age
, gender
, country
, region
.
2.) I think what i am doing here, is wrong. The user is given the option to filter the self.humanArray
. The user may filter using one, more or none of the following criteria;
name, age, gender, country or region.
My code looks like this;
NSArray *fRegionArray= [self.humanArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"regionIN %@ ", regionArray]];
NSArray *fCountryArray= [fRegionArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"country IN %@ ", countryArray]];
NSArray *fNameArray= [fCountryArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"name IN %@ ", nameArray]];
This code works, if the user selects all the filter attributes (region
, country
and name
). If you look at the above code you will notice that the output array of the 1st predicate is used for filtering in the 2nd predicate. So that is the reason for it to behave this way.
I need to modify the above code, so that the user would enter any of the attributes for filtering purposes. region
or country
or name
.
Upvotes: 1
Views: 447
Reputation: 9857
I did this in a project of mine Where I needed to filter an array of objects based on multiple criteria.
NSPredicate *filterBlock = [NSPredicate predicateWithBlock: ^BOOL(id obj, NSDictionary *criteria){
NSString *name = [criteria objectForKey:@"name"];
NSString *gender =....................
YourObject *yo = (YourObject*)obj;
if (yo.name isEqualToString:name && yo.gender isEqualToString:gender) {
// refine all your criteria
return YES;
} else {
return NO;
}
}];
NSArray *result = [arrayToBeFiltered filteredArrayUsingPredicate:filterBlock];
It worked, and it's not so bad concerning speed.
Upvotes: 1
Reputation: 490
Upvotes: 1