搜索控制器搜索字典数组

时间:2013-05-20 21:30:47

标签: ios uitableview nsarray nsdictionary uisearchdisplaycontroller

我正在尝试关注如何为UITableView实现搜索控制器的两个教程。到目前为止,这一切都正常,我的问题是搜索/过滤器本身:

教程链接:http://www.appcoda.com/how-to-add-search-bar-uitableview/ http://code-ninja.org/blog/2012/01/08/ios-quick-tip-filtering-a-uitableview-with-a-search-bar/

其中一个链接建议使用Predicate方法,我可以使用如下方法:

NSPredicate *resultPredicate = [NSPredicate
                                predicateWithFormat:@"SELF contains[cd] %@",
                                searchText];
self.searchResults = [self.fbFriends filteredArrayUsingPredicate:resultPredicate];

问题在于,上面没有考虑到我确实想要搜索self.fbFriends数组,但我想搜索该数组中的每个字典。数组设置为每个fb朋友都有一个字典,包括@“id”和@“name”。该表显示名称和字母顺序 - 这一切都正常。

我希望能够在self.fbFriends数组中的字典中进行搜索,并返回一个数组(self.searchResults),它是字典的过滤器数组。

第二篇教程选择了下面显示的另一条路线:

for (NSDictionary *friend in self.fbFriends) {
    NSRange textRange = [[friend objectForKey:@"name"]rangeOfString:searchText options:NSCaseInsensitiveSearch];
    if (textRange.location != NSNotFound) {
        [self.searchResults addObject:friend];
    } else {
        [self.searchResults removeObjectIdenticalTo:friend];
    }
}

这条路线的问题是我没有检查过滤的self.searchResults数组中是否已存在该对象,因此在每个字符输入后继续添加...我相信这可以解决,但我不知道认为这是最干净的方法。如果谓词最好,我怎样才能使用上面详述的数组/字典布局?

编辑 - 来自回答

self.searchResults = [self.fbFriends filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSDictionary *object, NSDictionary *bindings) {
     //get the value from the dictionary (the name value)
     NSString *name = [object objectForKey:@"name"];
                                                                 //check if the name contains the search string (you can change 
                                                                 //the validation to check if the name starts with 
                                                                 //the search string or ends etc.
    if([name rangeOfString:searchText].location != NSNotFound) {
        return YES;
    }
    return NO;
}]];

1 个答案:

答案 0 :(得分:3)

您可以使用谓词的块形式:

self.searchResult = [self.array filteredArrayUsingPredicate:[NSPredicate 
//since the array contains only dictionaries you can change the 
//type of the object which by default is `id` to NSDictionary
   predicateWithBlock:^BOOL(NSDictionart *object, NSDictionary *bindings) {
        //get the value from the dictionary (the name value)
        NSString *name = [object objectForKey:yourDictionaryNameKey];
        //check if the name contains the search string (you can change 
       //the validation to check if the name starts with 
       //the search string or ends etc.
      if([name rangeOfString:searchString].location != NSNotFound) { 
          return YES
      }
      return NO  
}]];

此外,您可能必须使用__block标识符声明searchString。