【问题标题】:Filter/Search NSMutableDictionary过滤/搜索 NSMutableDictionary
【发布时间】:2014-03-22 20:35:57
【问题描述】:

我有一个 NSMutableDictionary (PerosnsListSections) 和一个类名称 Persons

NSMutableDictionary:

  • 键是像“a,b,m ...”这样的字母
  • 值为 NSMutableArray -> NSMutableArray 有 Persons 类的对象

人物类: @property (assign,nonatomic) NSInteger pid; @property (strong,nonatomic) NSString *name;

现在我在 UITableView 中显示 PerosnsListSections,如图所示

我想要实现的是,当用户首先在搜索栏中键入时,我必须过滤作为第一个字母的部分,然后过滤该部分下的名称。

对不起我的英语不好(:

【问题讨论】:

  • 请注意,有几种不同的方法可以在一两行中“过滤”您想要的数组。但是这些通常不会比简单地写出明显的循环更快,并且在许多情况下它们可能会慢得多。写出你理解的循环与使用一些你读过但并不真正理解的神秘函数并没有什么可耻的。

标签: ios objective-c uisearchbar nspredicate nsmutabledictionary


【解决方案1】:

您可以先在字典中选择正确的数组,方法是:

NSString *firstLetter = [searchString substringWithRange:(NSRange){0,1}];
NSArray *people = PersonsListSection[firstLetter];

然后您可以使用NSPredicates 过滤人员:

NSPredicate *namesBeginningWithKeyword = [NSPredicate predicateWithFormat:@"(name     BEGINSWITH[cd] $letter)"];
NSArray *filteredPeople = [people filteredArrayUsingPredicate:[namesBeginningWithKeyword predicateWithSubstitutionVariables:@{@"letter": searchString}]]);

不过,如何在 tableview 的内容中反映这一点完全是另一个问题。

  1. 通常,您会希望您的视图控制器成为 UISearchBar 的委托,并使用 – (void)searchBar:textDidChange: 委托方法对更改做出反应。
  2. 在那里,您可以调用 tableview 的 - reloadData 方法,以便它尝试重新计算其内容,调用其所有 dataSource 方法,如 - numberOfSectionsInTableView: 等等。
  3. 反过来,在这些方法中,您需要检查是否在搜索栏中输入了某些文本,并使用上述提示返回正确的部分/单元格。

【讨论】:

  • 最好再次使用数组而不是字典,这样您就可以在 O(1) 中处理它的内容: NSArray *people= PersonsListSection[firstLetterCharacter-'a'] 。
  • NSDictionaries use a hash table 用于查找,因此平均查找时间为 O(1),最坏的情况为 O(log n),因此您不会丢失太多。此外,使用数组意味着预分配尽可能多的子数组,因为可以有不同的首字母。
  • 字典仍然包含 25 个数组,每个字母一个,所以这并不意味着浪费更多的内存。对于以不同字母开头的每个单词,散列也很可能会有所不同,但这并没有说明。这是一个实现细节,也可能会发生25个不同字母的单词放在同一个字典桶中。
  • 我想说它们的散列函数不太可能不具备基本的一致性属性,因此接近的数字(从 A 到 Z 的字母)会落入同一个 bin 中。此外,使用字典,您只需要分配您需要的那些,因此如果您只有一个名称要存储,那么您可能只有一个数组 - 这可以工作(字典中的缺失返回 nil,而字典中的缺失数组抛出异常)。它还可以演变为与拉丁语以外的不同字母一起使用。
  • 知道了,我创建了一个从原始 (PersonsListSection) 数组加载的本地 (filteredPeople) 数组。这个本地数组是视图中显示的数组。并在搜索中过滤原始数组(PersonsListSection)和保存在(filteredPeople)中的结果,然后重新加载tableview(:
猜你喜欢
  • 2020-08-16
  • 2013-03-13
  • 2014-12-31
  • 2021-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多