NSPredicate:将CONTAINS与IN结合使用

net*_*000 10 core-data nspredicate

我在CoreData中有一组用户,在我的应用程序中有一个搜索字段.用户具有属性名字和名称.

目前我有一个谓词"user.name CONTAINS [c]%@ OR user.firstname CONTAINS [c]%@"

这一直有效,直到用户输入"john smith"这样的全名.即使他输入"john sm",也应找到John Smith-Object.

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

Mar*_*n R 36

我不认为你可以在谓词中将"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);
Run Code Online (Sandbox Code Playgroud)

此示例生成谓词

(user.name CONTAINS[c] "John" OR user.firstname CONTAINS[c] "John") AND
(user.name CONTAINS[c] "Sm" OR user.firstname CONTAINS[c] "Sm")
Run Code Online (Sandbox Code Playgroud)

这将匹配"约翰史密斯",但不匹配"约翰米勒".

  • 进入iOS 5年,这是我第一次看到这个.这应该仍然是公认的答案. (3认同)

net*_*000 15

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)
Run Code Online (Sandbox Code Playgroud)

  • 这可能与@Martin R的答案相同,只是语言上的差异.你应该接受他的imo. (6认同)

San*_*Ray 5

斯威夫特 4 更新:

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

let orCompoundPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: 
[firstNamePredicate,lastNamePredicate]
Run Code Online (Sandbox Code Playgroud)

获取数据时使用orCompoundPredicate 。