Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple conditions in NSPredicate

How to use multiple conditions with NSPredicate?

I am using this but not getting anything in the returned array .

NSPredicate *placePredicate = [NSPredicate predicateWithFormat:@"place CONTAINS[cd] %@ AND category CONTAINS[cd] %@ AND ((dates >= %@) AND (dates <= %@)) AND ((amount >= %f) AND (amount <= %f))",placeTextField.text,selectedCategory,selectedFromDate,selectedToDate,[amountFromTextField.text floatValue],[amountToTextField.text floatValue]];

NSArray *placePredicateArray = [dataArray filteredArrayUsingPredicate:placePredicate];

NSLog(@"placePredicateArray %@", placePredicateArray);

The amount and the category can be empty sometimes. How should I construct the NSPredicate?

like image 445
Prerna chavan Avatar asked Apr 13 '12 11:04

Prerna chavan


2 Answers

You can build your placesPredicate using other NSPredicate objects and the NSCompoundPredicate class

Something like :

NSPredicate *p1 = [NSPredicate predicateWithFormat:@"place CONTAINS[cd] %@", placeTextField.text];
NSPredicate *p2 = [NSPredicate predicateWithFormat:@"category CONTAINS[cd] %@", selectedCategory];
NSPredicate *p3 = [NSPredicate predicateWithFormat:@"(dates >= %@) AND (dates <= %@)", selectedFromDate,selectedToDate];
NSPredicate *p4 = [NSPredicate predicateWithFormat:@"(amount >= %f) AND (amount <= %f)", [amountFromTextField.text floatValue],[amountToTextField.text floatValue]]; 

NSPredicate *placesPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[p1, p2, p3, p4]];

Now, if you are missing category for example you can just use a dummy YES predicate to replace it :

NSPredicate *p2;
if (selectedCategory) {
    p2 = [NSPredicate predicateWithFormat:@"category CONTAINS[cd] %@", selectedCategory];
} else {
    p2 = [NSPredicate predicateWithBool:YES]
}
like image 173
deanWombourne Avatar answered Nov 03 '22 11:11

deanWombourne


I would tend to handle this one piecemeal. That is,

placePredicate = [NSPredicate predicateWithFormat:@"place CONTAINS[cd] %@",placeTextField.text];
NSMutableArray *compoundPredicateArray = [ NSMutableArray arrayWithObject: placePredicate ]; 

if( selectedCategory != nil ) // or however you need to test for an empty category
    {
    categoryPredicate = [NSPredicate predicateWithFormat:@"category CONTAINS[cd] %@",selectedCategory];
    [ compoundPredicateArray addObject: categoryPredicate ];
    }

// and similarly for the other elements.  

Note that I don't bother even putting into the array the predicate for category (or anything else) when I know there isn't one.

// Then
    NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:
                                  compoundPredicateArray ];

And if I were planning to do it a lot, I wouldn't use the format method, but keep around the building blocks and just change whatever changes between uses.

like image 23
DRVic Avatar answered Nov 03 '22 12:11

DRVic