2011-02-14 46 views
10

在我的iOS应用程序中,我有一个非常简单的谓词,用于获取控制器。用于多字搜索的NSPredicate

NSString *format = [NSString stringWithFormat:@"name like[c] '%@'", nameVar]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:format]; 
[fetchController setPredicate:predicate]; 

它执行基本的不区分大小写的名称查找。现在我想改变它,以便我可以在搜索框中输入一些单词(nameVar具有搜索框中的值),并用空格分隔,并使用谓词过滤匹配所有这些关键字的结果。

所以,如果我有两个名字: “约翰史密斯”和“玛丽史密斯”,我搜索:“史密斯M”我想只有一个结果,但像这样的搜索:“Sm th ith”应该返回两个值。

有没有人有一个想法应该如何实施?

回答

31

编辑回一个普通的计算机上...

因此,有几件事情需要注意的:

  1. 你并不需要把引号替换占位符在格式字符串。当该方法构建谓词时,它将创建一个抽象语法树NSExpressionNSPredicate(具体为NSComparisonPredicateNSCompoundPredicate)对象。您的字符串将被放置到类型NSConstantValueExpressionTypeNSExpression,这意味着它已经已被解释为常规字符串。事实上,将单引号放在格式字符串中会使谓词不起作用。
  2. 您不仅限于谓词中的单个比较。从它的声音中,您想要搜索字符串中的“单词”(nameVar)具有尽可能多的比较结果。在这种情况下,我们会将nameVar分解为其组成单词,并为每个单词创建一个比较。一旦我们完成了,我们AND他们一起创建一个单一的总体谓词。下面的代码确实如此。

原来的答案

您可以通过建立自己的NSCompoundPredicate做到这一点:

NSString *nameVar = ...; //ex: smith m 
NSArray *names = ...; //ex: John Smith, Mary Smith 

NSArray *terms = [nameVar componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 
NSMutableArray *subpredicates = [NSMutableArray array]; 

for(NSString *term in terms) { 
    if([term length] == 0) { continue; } 
    NSPredicate *p = [NSPredicate predicateWithFormat:@"name contains[cd] %@", term]; 
    [subpredicates addObject:p]; 
} 

NSPredicate *filter = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates]; 
[fetchController setPredicate:filter]; 

警告:在我的iPhone浏览器中键入。

+0

因此,在我运行这段代码之后,我可以在哪里找到我的结果? subpredicates?我是iOS开发人员的初学者,如果问题很愚蠢,我很抱歉:) – 2015-10-18 14:46:52