我正在尝试创建具有多个条件的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];
答案 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
密钥路径。
在以下情况下过滤数组会抛出异常:
businessArea
值(例如,它不是具有-businessArea
方法的对象)< / LI>
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”判断,它是一个集合,即 NSArray
、NSSet
或 NSDictionay
项。在这种情况下, "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
你会看到那里是什么谓词的最终形式,并将能够确定您是否正确构建了它。