NSPredicate中的多个条件

时间:2012-04-13 11:58:15

标签: objective-c ios cocoa-touch ipad 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

3 个答案:

答案 0 :(得分:30)

您可以使用其他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]
}

答案 1 :(得分:13)

我倾向于处理这一件零碎的事。也就是说,

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

如果我打算做很多事情,我不会使用格式化方法,而是保留构建块,只需改变使用之间的任何变化。

答案 2 :(得分:0)

read

您可以阅读这篇文章Array Filter Using Blocks

  

在Swift中

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