我在CoreData中有一组用户,在我的应用程序中有一个搜索字段。用户具有属性名字和名称。
目前我有一个谓词“user.name CONTAINS [c]%@ OR user.firstname CONTAINS [c]%@”
这一直有效,直到用户输入“john smith”这样的全名。即使他输入“john sm”,也应找到John Smith-Object。
将搜索词的数组(IN)与CONTAINS组合起来的谓词是什么?
答案 0 :(得分: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);
此示例生成谓词
(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”。
答案 1 :(得分:14)
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)
答案 2 :(得分:0)
我遇到了同样的问题并解决了这个问题:
在我的NSManagedObject类(用户)中,我添加了以下方法,将这两个值合并为一个字符串:
- (NSString *)name
{
return [NSString stringWithFormat:@"%@ %@", self.firstname, self.lastname];
}
然后你只需要以下几行来匹配你的列表,在我的例子中是一个带有用户对象的NSArray:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchString];
NSArray *filteredUsers = [users filteredArrayUsingPredicate:predicate];
答案 3 :(得分:0)
Swift 4更新:
let firstName = NSPredicate(format: "firstName CONTAINS[c] %@", searchText)
let lastName = NSPredicate(format: "lastName CONTAINS[c] %@", searchText)
let orCompoundPredicate = NSCompoundPredicate(orPredicateWithSubpredicates:
[firstNamePredicate,lastNamePredicate]
在获取数据时使用或CompoundPredicate 。