所以我想在Swift中快速将项目分组

介绍

在我们的编程生涯中,有时需要对数据集合进行分类和分组。 排序本身是一个简单的概念-列出未排序的数据列表,并根据一组规则对其进行排序。 是您执行或使您感到沮丧的实现。

以手机中的联系人列表为例。 根据您的情况,该列表可能很小,也可能很长(有时不合理)。 这就是为什么在大多数操作系统上都可以导航到列表中所需位置的方法,而不必花太多时间浏览。 这可以通过排序和分组来实现。 您设置了一些规则,应用程序将进行相应排序。 该实现需要能够快速处理大量数据,否则打开“​​联系人”应用会变得很麻烦。


假设我向互联网机器查询了过去二十年来发行的所有电影的列表。 如果要在iOS应用中显示该图片,则需要按字母顺序对其进行排序,因为我们每年要谈论成千上万部电影。 我想要的UI很简单,将UITableView分组为AZ部分,并且在右侧有一个部分索引标题栏,这使我可以像rolodex一样向下滑动列表

我已经多次看到类似的实现:

 令u = u中的v表示“ ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789” 
var x = [Movies]()for电影中的y {
如果让z = y.name.prefix(1),则z == v {
临时附加(y)
}
}

indexedList.append((v,x))}

松散地,正在做的是遍历字母和每个匹配的电影,使数据结构如下:

  [(“ A”:[电影,电影,电影]),(“ B”:[电影,电影]),(“ C” ...)] 

该算法的时间复杂度可能为O(n²) ,因为每次外循环运行N次 ,内循环运行M次。 换句话说,电影列表越长,实现就越需要时间来完成。 将其与iPhone 6配合使用,几乎要花整整两秒钟的时间才能对15,000件物品进行排序。 令人沮丧的缓慢。

让我们使用字典分组

通过在Swift中使用字典分组,我们可以在某种程度上克服这一问题。 我拿了电影清单,写了一个谓词:

 让谓词:(电影)->字符串{ 
警卫让c =字符串($ 0.title.prefix(1))否则{fatalError()}

让字母=“ ABCDEFGHIJKLMNOPQRSTUVWXYZ”
如果字母。contains(c){,则让数字=“ 0123456789” {
返回c
}否则,如果numeric.contains(c){
返回“#”
}其他{
返回“?”
}
}

我已经在谓词中定义了规则。 如果电影的标题以字母字符开头,则将该电影分类为适当的类别。 如果电影的标题以数字开头,则将其归为# ,最后归为? 如果不符合以上任何条件。

然后,我创建了一个词典,给它以我的谓词,并按升序对其进行排序。

 让分组=字典(分组:电影,通过:谓词) 
.sorted {$ 0.0 <$ 1.0}

这导致了我想要的数据结构。 在iPhone 6上,排序时间从2秒减少到只有146ms(或0.146秒),可以对15,000个项目进行排序。 我还在iPhone X上进行了采样,结果25毫秒(0.025秒)令人惊讶。


您还可以通过其他方式使用字典分组。 假设您希望存储UI中的UISwitch数组,将isOn!isOn

 让switchArray = tableView.visibleCells.map {$ 0.accessoryView为!  UISwitch}让switchs = Dictionary(分组:switchArray,按:{$ 0.isOn})。sorted {$ 0.0> $ 1.0} //我没有测试过,所以语法可能是错误的。 切勿复制/粘贴伪代码。 

结论

决定如何对数据进行分区。 您可以重新发明轮子,也可以直接使用Swift提供给您的东西。 希望这篇文章给您一些动力来改进您的应用程序或学习Swift!