NSArray 上的 NSPredicate 用于搜索任何对象
Posted
技术标签:
【中文标题】NSArray 上的 NSPredicate 用于搜索任何对象【英文标题】:NSPredicate on an NSArray to search for any object 【发布时间】:2013-09-16 07:45:32 【问题描述】:我有一个包含名称、地址、电话的对象数组。没有,等等。
我希望能够在数组中搜索任何出现的术语 - 无论是在名称字段、地址字段等中。
我有这样的想法:
-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
// Update the filtered array based on the search text and scope.
// Remove all objects from the filtered search array
[self.searchResults removeAllObjects];
// Filter the array using NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",searchText];
searchResults = [NSMutableArray arrayWithArray:[contactArray filteredArrayUsingPredicate:predicate]];
这会导致异常“Can't use in/contains operator with collection”。
更新。我现在最多可以搜索三个字段。当我添加第四个(以任何顺序)时,我得到了这个异常:“无法解析格式字符串......”
谓词代码现在是:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.narrative contains[c] %@ OR SELF.category contains[c] %@ OR SELF.date contains[c] OR SELF.name contains[c] %@", searchText, searchText, searchText, searchText];
searchResults = [NSMutableArray arrayWithArray:[allDreams filteredArrayUsingPredicate:predicate]];
三个是谓词搜索字段的限制吗?我该如何解决这个问题?再次感谢。
【问题讨论】:
【参考方案1】:只需使用一个谓词字符串来检查它们:
@"name contains[cd] %@ OR address contains[cd] %@"
您可以根据需要添加任意数量。
唯一的缺点是您需要为每个要测试的字段添加相同的搜索字符串,这看起来有点难看。
如果您的对象是字典,那么有一种方法可以真正搜索所有值,而不必在编译时知道它们的名称,使用子查询。
它是这样工作的:
@"subquery(self.@allValues, $av, $av contains %@).@count > 0"
它对字典对象使用@allValues
特殊键(或方法调用,如果您愿意),并使用它来过滤包含您的搜索字符串的任何值。如果找到任何对象(即计数为正),则该对象将包含在结果中。
请注意,这将不加选择地检查所有值,即使是那些您不想包含在字典中的值。
【讨论】:
@DavidDelMonte 注意到它们是两个非常不同的答案——Kjuly 提出了两种检查一个字段的方法,而我的提出了一种检查多个字段的方法。因此,不要只是尝试它们,而是要确保您了解您需要什么以及正确的解决方案是什么。 此外,您可以使用NSCompoundPredicate
动态创建简单的谓词并使用+orPredicateWithSubpredicates:
连接它们。
@all,Monolo 的答案接近我想要的,但我意识到这比我在我的问题中提出的要复杂。我必须弄清楚如何包含特殊字符(例如空格)和来自多个数组的项目 - 包括多对多关系。我认为这将是一个轻松的早晨......
@DavidDelMonte 我的猜测是异常的描述告诉你。但无论如何,您的字符串中存在语法错误:SELF.date
字段缺少%@
。所以问题不在于添加的字段数量。
@Ryan 只需将 [CD] 修饰符应用于谓词字符串:“... contains[cd] ...”【参考方案2】:
我认为你的数组项不是纯字符串,对吧?
假设你的数组项包含name
属性(即使是字典),你可以这样搜索:
NSPredicate * predicate =
[NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@ OR name LIKE[cd] %@", searchText, searchText];
这里,name
可以是SELF.name
。
HERE是官方文档。
【讨论】:
Kjuly,在这个数组中,每个对象都是一个字符串对象。我尝试过使用 SELF.name CONTAINS[c],但这只是查看第一个字段。我将尝试使用 [cd]。也感谢您的链接。 @DavidDelMonte 字符串对象怎么会包含名称、地址?你的意思是这样的:name:<name>,address:<address>
?为什么不把它格式化成@name: <name>, address: <address>
? ;)以上是关于NSArray 上的 NSPredicate 用于搜索任何对象的主要内容,如果未能解决你的问题,请参考以下文章