5月27日 11:29

Swift Array、Set、Dictionary 有什么区别?怎么选?

Swift 有三种集合类型:Array(有序、可重复)、Set(无序、不可重复)、Dictionary(键值对)。选哪个看需求:需要顺序和索引用 Array,需要去重和集合运算用 Set,需要键值查找用 Dictionary。

Array 是最常用的——按下标随机访问 O(1),尾部插入删除 O(1),中间插入删除 O(n)。Set 基于 HashMap,查找/插入/删除都是 O(1),但不能保序。Dictionary 也是 HashMap,键必须可哈希,下标访问返回 Optional(键可能不存在)。

追问

Set 的集合运算有哪些?实际用在哪?

并集(union)、交集(intersection)、差集(subtracting)、对称差集(symmetricDifference)。实际场景:标签系统——"用户A的标签和用户B的标签有多少重叠"用交集,"A有B没有的"用差集,"两人不同时拥有的"用对称差集。Set 比 Array 做这些操作快得多——Array 的 contains 是 O(n),Set 是 O(1)。

Dictionary 的下标访问为什么返回 Optional?

因为键可能不存在。如果下标直接返回值类型,访问不存在的键就会崩溃。返回 Optional 让你安全处理两种情况:if let value = dict["key"] 安全解包,dict["key"]! 强制解包(确定存在时)。这比 NSDictionary 的返回 AnyObject? 更安全——Swift 的类型系统保证了值的类型。

什么时候用 Array,什么时候用 Set?

需要顺序或允许重复用 Array。去重或集合运算用 Set。一个常见误区:去重时先 Array 再手动过滤——直接用 Set 初始化就行了:Set(array).sorted()。另外 Set 不保序,如果去重后还要保持原始顺序,得用 reduce 手动构建有序数组,或者用 Swift 5.7+ 的 OrderedCollections 库。

集合类型作为函数参数时应该传值还是传引用?

Array、Set、Dictionary 都是值类型(struct),传参时默认拷贝。Swift 有写时复制(Copy-on-Write)优化——只有实际修改时才真正拷贝,所以大数组传参不会浪费内存。但如果函数内部需要修改集合并影响调用方,需要用 inout 参数:func append(_ item: Int, to array: inout [Int])

Dictionary 怎么安全地修改值?

用下标修改时,键不存在会自动插入 nil 值。用 updateValue(_:forKey:) 返回旧值(Optional),可以知道是更新还是新增。最常见的模式是"有就更新,没有就插入默认值":dict[key, default: 0] += 1——比先判断再操作简洁得多。

写段代码

swift
// Array 基本操作 var nums = [3, 1, 4, 1, 5] nums.sort() // [1, 1, 3, 4, 5] nums.append(9) // 尾部插入 O(1) // Set 去重和集合运算 let a: Set = [1, 2, 3, 4] let b: Set = [3, 4, 5, 6] a.intersection(b) // {3, 4} a.symmetricDifference(b) // {1, 2, 5, 6} // Dictionary 安全操作 var freq: [String: Int] = [:] freq["apple", default: 0] += 1 // 安全递增,不存在时默认0 freq.updateValue(5, forKey: "banana") // 返回旧值 // 去重但保持顺序 let items = [3, 1, 4, 1, 5, 3] var seen = Set<Int>() let unique = items.filter { seen.insert($0).inserted }
标签:Swift