NSPredicate具有多种条件

时间:2014-09-03 03:59:18

标签: ios objective-c nspredicate

我正在尝试创建具有多个条件的NSPredicate。我找到了几个解决方案,但它们似乎都没有使用我的方法。我发现的最好看的是下面的。

这是我的单一谓词方法,它运行得很好:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", 
searchText];
filteredBusinesses = [businesses filteredArrayUsingPredicate:predicate];

这是我编辑的多个条件版本。我不确定什么是错的。有什么想法吗?

NSPredicate *p1 = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];
NSPredicate *p2 = [NSPredicate predicateWithFormat:@"businessArea contains[c] %@", 
searchText];

NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[p1, p2]];
filteredBusinesses = [businesses filteredArrayUsingPredicate:predicate];

5 个答案:

答案 0 :(得分:17)

你可以试试这个

NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[p1, p2]];

答案 1 :(得分:9)

除了@Nikunj的回答,您还可以使用NSCompoundPredicate进行AND操作。

Obj-C - AND

NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"X == 1"];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"X == 2"];
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[predicate1, predicate2]];

Swift - AND

let predicate1:NSPredicate = NSPredicate(format: "X == 1")
let predicate2:NSPredicate = NSPredicate(format: "Y == 2")
let predicate:NSPredicate  = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1,predicate2] )

Swift 3 - AND

    let predicate1 = NSPredicate(format: "X == 1")
    let predicate2 = NSPredicate(format: "Y == 2")
    let predicateCompound = NSCompoundPredicate.init(type: .and, subpredicates: [predicate1,predicate2])

答案 2 :(得分:1)

您发布的代码中没有任何错误,这意味着错误可能来自您通过过滤数组评估谓词时。

由于第一个谓词起作用,问题在于businessArea密钥路径。

在以下情况下过滤数组会抛出异常:

  1. 数组中的一个对象没有businessArea值(例如,它不是具有-businessArea方法的对象)< / LI>
  2. 该对象的值为businessArea,但该值不是NSString也不是nil

答案 3 :(得分:1)

NSCompoundPredicate进行了改版。以防万一有人在寻找Swift 5+版本:

AND

let predicatesAND = NSCompoundPredicate(andPredicateWithSubpredicates:[pred1,pred2])

OR

let predicatesOR = NSCompoundPredicate(orPredicateWithSubpredicates:[pred1,pred2])

答案 4 :(得分:0)

首先,我怀疑您的两个基本谓词可能存在缺陷。根据您的对象名称“businesses”判断,它是一个集合,即 NSArrayNSSetNSDictionay 项。在这种情况下, "name contains[c] 'mmm'" 在对整个集合进行评估时没有意义,应该会崩溃。它缺少集合运算符 (ANY, ALL, SOME) ,例如"ANY name contains[c] 'mmm'"

啊...现在我明白了...您正在使用谓词来过滤 NSArray,这意味着谓词分别对每个项目执行。所以你的谓词没问题。

现在……组合谓词的最简单方法是在格式字符串级别!怎么了

NSPredicate *p1 = [NSPredicate predicateWithFormat:@"name contains[c] %@ AND businessArea contains[c] %@", nameToSearch, areaToSearch]; 

如果你坚持以艰难的方式去做,那么构建你的复合 NSPredicate 也应该有效 - 只有你对两个条件使用相同的 searchText,这可能导致谓词永远不匹配。

我给你的建议,在评估过滤数组的行上放置一个断点并在过滤之前停止,并在调试器中打印谓词描述,使用调试器命令 po p1 你会看到那里是什么谓词的最终形式,并将能够确定您是否正确构建了它。