Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building a NSPredicate for a filter

Just wondering what the best way to build a NSPredicate is if some filters are optional?

This is basically for a filter, so if some options aren't selected I don't to filter by them

eg. If I have option1 and option2 set for the filter.

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"option1 = %@ AND option2 = %@] ....

otherwise if just option1 NSPredicate* predicate = [NSPredicate predicateWithFormat:@"option1 = %@] ....

The key being there are 10 different options to filter, so I don't want to have to code for the 10x10 possible combinations.

Thanks

like image 876
John Avatar asked Apr 15 '10 07:04

John


2 Answers

John, have a look at building and retaining the "sub-predicates" as templates and then use your logic branches to build a compound predicate to perform the filtering

/* Retain these predicate templates as properties or static variables */
NSPredicate *optionOneTemplate = [NSPredicate predicateWithFormat:@"option1 = $OPTVALUE"];
// .. and so on for other options

NSMutableArray *subPredicates = [NSMutableArray arrayWithCapacity:10];

/* add to subPredicates by substituting the current filter value in for the placeholder */
if (!!optionOneValue) {
  [subPredicates addObject:[optionOneTemplate predicateWithSubstitutionVariables:[NSDictionary dictionaryWithObject:optionOneValue forKey:@"OPTVALUE"]]];
}
// .. and so on for other option values

/* use the compound predicate to combine them */
NSPredicate *filterPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];

// Now use your filterPredicate

You might want to use a dictionary to keep the set of predicate templates nice and organised, but the example above shows the basic steps.

Rob.

like image 99
ohhorob Avatar answered Oct 23 '22 15:10

ohhorob


predicateWithFormat: takes an NSString. So all you have to do is build the string based on the options selected (using a for-loop to append to an NSMutableString, etc.) and pass it to predicateWithFormat:

like image 41
diederikh Avatar answered Oct 23 '22 15:10

diederikh