Swift:如何对多维数组执行去重操作
Swift多维数组去重的几种简洁实现方式
嘿,作为Swift新手碰到这种多维数组去重的问题太常见啦!不用自己从头写复杂的去重函数,Swift本身有不少简洁的实现方式,我给你整理几个常用的:
方法一:利用Set去重(适合固定长度的子数组)
因为Swift的Array本身是引用类型,不能直接放进Set,但如果你的子数组都是固定长度(比如这里都是两个Int元素),可以先转成元组(值类型,且元素为Hashable时元组自动符合Hashable),再用Set去重,最后转回数组:
let arr = [[1,2],[1,2],[3,4],[3,4],[4,5]] // 将子数组转为(Int, Int)元组 let uniqueTuples = Set(arr.map { ($0[0], $0[1]) }) // 把元组转回数组 let uniqueArr = uniqueTuples.map { [$0.0, $0.1] }
⚠️ 注意:Set是无序集合,所以最终数组的顺序可能和原数组不一致。如果需要保持原顺序,看下面的方法。
方法二:保持原顺序的基础实现(简单直观)
用Array的reduce方法结合contains,遍历原数组时只保留第一次出现的元素:
let arr = [[1,2],[1,2],[3,4],[3,4],[4,5]] let uniqueArr = arr.reduce([]) { result, current in // 如果结果数组里没有当前元素,就添加进去,否则保持原结果 result.contains(current) ? result : result + [current] } // 输出结果:[[1,2],[3,4],[4,5]],顺序和原数组一致
这种方法代码易懂,但如果数组很大,contains的O(n)复杂度会让整体效率变低,适合小数据量的场景。
方法三:高效保持顺序的实现(Swift 5.1+)
利用Swift 5.1+中Dictionary的有序特性,把数组元素作为字典的key(重复key会被自动覆盖),最后取字典的keys即可:
let arr = [[1,2],[1,2],[3,4],[3,4],[4,5]] // 用子数组作为key,值随便填个占位符 let uniqueDict = Dictionary(arr.map { ($0, ()) }, uniquingKeysWith: { _, _ in () }) // 把字典的keys转成数组,顺序和原数组中元素第一次出现的顺序一致 let uniqueArr = Array(uniqueDict.keys)
这种方法的时间复杂度更优(O(n)),而且能完美保持原顺序,适合大数据量的场景。
额外提示:子数组长度不固定的情况
如果你的子数组长度不固定,可以给Array扩展一个Hashable的实现(需要元素都是Hashable),这样就能直接用Set或者上面的字典方法了,比如:
extension Array: Hashable where Element: Hashable { public func hash(into hasher: inout Hasher) { hasher.combine(count) for element in self { hasher.combine(element) } } }
扩展后,就可以直接用Set(arr)去重,或者用上面的字典方法啦!
内容的提问来源于stack exchange,提问作者smokinguns
相关产品推荐
相关产品推荐

