Множество условий в NSPredicate
Как использовать несколько условий с NSPredicate
?
Я использую это, но ничего не получаю в возвращаемом массиве.
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);
Количество и категория иногда могут быть пустыми. Как мне создать NSPredicate
?
Ответы
Ответ 1
Я хотел бы обработать это по частям. То есть
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.
Обратите внимание, что я не беспокоюсь даже поместить в массив предикат для категории (или что-то еще), когда я знаю, что его нет.
// Then
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:
compoundPredicateArray ];
И если бы я планировал сделать это много, я бы не использовал метод format, но поддерживал строительные блоки и просто изменял любые изменения между использованием.
Ответ 2
Вы можете создать свой placesPredicate
с помощью других объектов NSPredicate
и класса NSCompoundPredicate
Что-то вроде:
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]];
Теперь, если вам не хватает категории, вы можете просто использовать предикат фиктивного YES
, чтобы заменить его:
NSPredicate *p2;
if (selectedCategory) {
p2 = [NSPredicate predicateWithFormat:@"category CONTAINS[cd] %@", selectedCategory];
} else {
p2 = [NSPredicate predicateWithBool:YES]
}
Ответ 3
Suppose a class Person with attributes "name", "age", "income"
"personArray" is array of class Person
NSPredicate *mypredicate = [NSPredicate predicateWithBlock:^BOOL(personObj Person, NSDictionary *bindings) {
NSNumber *age = personObj.age;
String *name = personObj.name;
NSNumber *income = personObj.income
BOOL result = (age > 20 && name == "Stack" && income >40000);
return result;
}];
NSArray *filteredArray = [personArray filteredArrayUsingPredicate: mypredicate];
Далее вы можете прочитать эту статью Фильтр массивов с использованием блоков
В Swift
let filterArray = personArray.filter
{ person in
let age = personObj.age;
let name = personObj.name;
let income = personObj.income
BOOL result = (age > 20 && name == "Stack" && income >40000);
return result;
}