Swift中不同类型数组依据指定属性对比提取差异元素的实现问题
实现方案
最简实现
先将[MyFile]的所有fileName提取为Set,利用Set的O(1)查询特性提升过滤效率,再直接筛选[Quiz]即可:
// 提取所有已下载的文件名存入Set let downloadedFileNames = Set(myFile.map(\.fileName)) // 筛选title没有对应fileName匹配的Quiz let unDownloadedQuiz = allQuiz.filter { !downloadedFileNames.contains($0.title) }
通用扩展实现
如果需要复用这种跨类型数组按指定属性对比的逻辑,可以扩展Array实现通用方法:
extension Array { /// 筛选出当前数组中,指定属性值不存在于另一数组对应属性值集合中的元素 /// - Parameters: /// - selfKeyPath: 当前数组元素参与对比的属性KeyPath /// - otherArray: 用于对比的另一数组 /// - otherKeyPath: 对比数组元素参与对比的属性KeyPath /// - Returns: 符合条件的元素数组 func filter<Value: Hashable, OtherElement>(by selfKeyPath: KeyPath<Element, Value>, notIn otherArray: [OtherElement], _ otherKeyPath: KeyPath<OtherElement, Value>) -> [Element] { let otherValueSet = Set(otherArray.map { $0[keyPath: otherKeyPath] }) return self.filter { !otherValueSet.contains($0[keyPath: selfKeyPath]) } } }
调用方式非常简洁:
unDownloadedQuiz = allQuiz.filter(by: \.title, notIn: myFile, \.fileName)
性能说明
将对比属性提取为Set后,整体时间复杂度为O(m + n)(m、n分别为两个数组的长度),远优于直接用数组contains遍历的O(m * n),适合数组元素数量较多的场景。
内容的提问来源于stack exchange,提问作者Ufuk Köşker
相关产品推荐
相关产品推荐

