ios - 过滤具有大量对象的数组的唯一名称
问题描述
我目前正在获取许多包含街道名称和坐标的对象。返回的数组有大约 22.000 个对象,我们想要的结果数组有大约 4000 个,其余的都是重复的。这种数据的问题是获取的对象可以具有相同的名称但不同的坐标,我只对基于唯一名称获取对象感兴趣。如果有多个具有相同名称的对象,我只想保留第一个对象。
到目前为止,我一直在尝试通过比较名称来遍历街道。我宁愿使用filter
或其他更高效的解决方案。
我的结构
struct StreetName {
var name: String
var polyLine: CLLocationCoordinate2D
}
到目前为止我的代码
DataManager.shared.getStreetNames { (streets) in
var namesArray: [StreetName] = []
for streetName in streets {
let name = streetName.name
if namesArray.count == 0 {
namesArray.append(streetName)
} else if namesArray.contains(where: {$0.name == name }) {
/* Dont add */
} else {
namesArray.append(streetName)
}
}
self.streetNames = namesArray.sorted(by: {$0.name < $1.name})
self.filteredStreetNames = self.streetNames
OperationQueue.main.addOperation {
self.streetTableView.reloadData()
}
}
此代码块有效,但在 iPhone X 上运行大约 30 秒。这太慢了。有任何想法吗?
解决方案
我认为,如果您对此进行分析,您会发现sort
花费的时间最多。我找不到官方说明,但很有可能底层实现是快速排序,当数组已经排序(或数组以相反的顺序排序)时,它的复杂性最差。
快速排序的平均情况复杂度为 O(n log n),但在最坏的情况下为 O(n 2 )。
我认为您应该改为实现插入排序,或者更准确地说,始终将新元素插入到已经排序的位置。这应该将整个函数的复杂性降低到 O(n)。
伪代码:
- 获取街道名称
- 对于每个街道名称
- 在现有数组中找到街道名称所在的位置(我建议二进制搜索,因为数组已经排序)
- 如果街道名称已经存在,请跳过
- 如果名称不存在,请插入它。
结果应该是唯一街道名称的排序数组,要求每个名称只被读取和插入一次。
推荐阅读
- c# - BaseController 和特定控制器上的 OnActionExecution
- angular - 为什么 angular mat-select 调用 tiwce 并更改
- ionic-framework - cordova-plugin-ble-central 自动连接功能总是提示用户配对设备
- c - 文件关闭时检测到堆栈粉碎
- lambda - 如何在呼叫流程中引用 StartOutboundVoiceContact API 属性?
- powershell - PowerShell 帮助 - 使用公式添加长度以在 Outout 文件中以 MB 为单位显示
- google-sheets - 如何在谷歌工作表中获取从 n 到 n+m 的排序值?
- javascript - 在 C# WebApp 中显示 PDF 文档时出错
- plugins - 第三方社交媒体 Feed 和 LI 不再工作
- java - 将数据库中的数据显示到android表中