NSPredicate在NSArray上搜索任何对象

时间:2013-09-16 07:45:33

标签: ios objective-c arrays nspredicate

我有一个带有名字,地址和电话的对象数组。没有,等等。

我希望能够在数组中搜索任何出现的术语 - 无论是在名称字段,地址字段等中。

我有这样的想法:

-(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]];
}

这会导致异常"无法在/ contains运算符中使用集合"。

更新。我现在可以搜索最多三个字段。当我添加第四个(以任何顺序)时,我得到这个例外:"无法解析格式字符串..."

Predicate代码现在是:

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]];

谓词搜索字段有三个限制吗?我该如何解决这个问题?再次感谢。

2 个答案:

答案 0 :(得分:17)

只需使用一个谓词字符串来检查它们:

@"name contains[cd] %@ OR address contains[cd] %@"

您可以添加任意数量的内容。

唯一的缺点是,您需要为要测试的每个字段添加相同的搜索字符串,这看起来有点难看。

如果您的对象是字典,那么有一种方法可以在编译时使用子查询真正搜索所有值,而无需知道它们的名称。

它的工作原理如下:

@"subquery(self.@allValues, $av, $av contains %@).@count > 0"

它使用@allValues特殊键(或方法调用,如果您愿意)用于字典对象,并使用它来过滤包含搜索字符串的任何值。如果找到任何(即,计数为正),则该对象包含在结果中。

请注意,这会不加选择地检查所有值,即使您在字典中有任何值也不想包含这些值。

答案 1 :(得分:4)

我认为你的数组项不是纯字符串,对吗?

假设您的数组项包含name属性(即使它是字典),您可以这样搜索它:

NSPredicate * predicate =
  [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@ OR name LIKE[cd] %@", searchText, searchText];

此处,name可以是SELF.name


HERE是一份官方文件。