NSPredicate:将 CONTAINS 与 IN 结合

Posted

技术标签:

【中文标题】NSPredicate:将 CONTAINS 与 IN 结合【英文标题】:NSPredicate: Combine CONTAINS with IN 【发布时间】:2012-11-20 18:16:46 【问题描述】:

我在 CoreData 中有一组用户,在我的应用程序中有一个搜索字段。用户具有属性 firstname 和 name。

目前我有一个谓词,例如“user.name CONTAINS[c] %@ OR user.firstname CONTAINS[c] %@”

在用户输入全名(如“john smith”)之前,此方法有效。即使他输入“john sm”,也应该找到 John Smith-Object。

将搜索词数组 (IN) 与 CONTAINS 组合的谓词是什么?

【问题讨论】:

你能帮忙看看一个类似的问题吗?谢谢! ***.com/questions/62380694/… 【参考方案1】:

我认为您不能在谓词中将“IN”与“CONTAINS”结合起来。但是您可以将搜索字符串拆分为单词,并创建一个“复合谓词”:

NSString *searchString = @"John  Sm ";
NSArray *words = [searchString componentsSeparatedByString:@" "];
NSMutableArray *predicateList = [NSMutableArray array];
for (NSString *word in words) 
    if ([word length] > 0) 
        NSPredicate *pred = [NSPredicate predicateWithFormat:@"user.name CONTAINS[c] %@ OR user.firstname CONTAINS[c] %@", word, word];
        [predicateList addObject:pred];
    

NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicateList];
NSLog(@"%@", predicate);

这个例子产生了谓词

(user.name CONTAINS[c] "John" OR user.firstname CONTAINS[c] "John") AND
(user.name CONTAINS[c] "Sm" OR user.firstname CONTAINS[c] "Sm")

将匹配“John Smith”,但不匹配“John Miller”。

【讨论】:

进入 ios 5 年,这是我第一次看到这个。这仍然应该是 imo 接受的答案。 @Martin R,你能帮忙看看类似的问题吗? ***.com/questions/62380694/…【参考方案2】:

2.5 年后,我可以在 swift 中用一个更复杂的例子来回答我的问题:

var predicateList = [NSPredicate]()

let words = filterText.componentsSeparatedByString(" ")

for word in words

     if count(word)==0
           continue
     

     let firstNamePredicate = NSPredicate(format: "firstName contains[c] %@", word)
     let lastNamePredicate = NSPredicate(format: "lastName contains[c] %@", word)
     let departmentPredicate = NSPredicate(format: "department contains[c] %@", word)
     let jobTitlePredicate = NSPredicate(format: "jobTitle contains[c] %@", word)

     let orCompoundPredicate = NSCompoundPredicate(type: NSCompoundPredicateType.OrPredicateType, subpredicates: [firstNamePredicate, lastNamePredicate,departmentPredicate,jobTitlePredicate])

     predicateList.append(orCompoundPredicate)


request.predicate = NSCompoundPredicate(type: NSCompoundPredicateType.AndPredicateType, subpredicates: predicateList)

【讨论】:

这可能与@Martin R 的答案相同,只是语言不同。你应该接受他。 你能帮忙看看一个类似的问题吗?谢谢! ***.com/questions/62380694/…【参考方案3】:

Swift 4 更新:

let firstName = NSPredicate(format: "firstName CONTAINS[c] %@", searchText)
let lastName = NSPredicate(format: "lastName CONTAINS[c] %@", searchText)

let orCompoundPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: 
[firstNamePredicate,lastNamePredicate]

在获取数据时使用 orCompoundPredicate

【讨论】:

你能帮忙看看一个类似的问题吗?谢谢! ***.com/questions/62380694/…【参考方案4】:

我遇到了同样的问题并这样解决了:

在我的 NSManagedObject 类(用户)中,我添加了以下方法,将两个值合并为一个字符串:

- (NSString *)name

    return [NSString stringWithFormat:@"%@ %@", self.firstname, self.lastname];

那么你只需要以下几行来匹配你的列表,在我的例子中是一个带有用户对象的 NSArray:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchString];
NSArray *filteredUsers = [users filteredArrayUsingPredicate:predicate];

【讨论】:

这并不能解决用户搜索“lastname firstname”时的问题

以上是关于NSPredicate:将 CONTAINS 与 IN 结合的主要内容,如果未能解决你的问题,请参考以下文章

使用“CONTAINS”运算符时,带有 NSPredicate 的 CKQuery 失败

NSPredicate,CoreData 中的空格。如何修剪谓词?

CloudKit NSPredicate 不区分大小写

带有特殊字符的 NSPredicate 过滤

将 NSPredicate 与字符串匹配

将实体的自定义字段与 NSPredicate 一起使用