Swift 字典(Dictionary)全解析(2025 版)
“Dictionary 是无序、键值对、Hashable 键” —— 掌握 50+ 操作 ,写出 高效、安全、函数式 的键值存储代码!
一、Swift 字典核心特性
特性 说明 值类型 赋值时复制,线程安全 无序 插入顺序 ≠ 遍历顺序 唯一键 键必须唯一(自动覆盖) 键必须 Hashable String、Int 等默认支持动态大小 可增删键值对
let scores = ["张三": 95, "李四": 88] // [String: Int]
var config = [String: Any]() // 键值类型不同
二、创建字典
1. 字面量
let empty: [String: Int] = [:]
let grades = ["A": 90, "B": 80, "C": 70]
2. 类型推断
let user = ["name": "小明", "age": "18"] // [String: String]
3. 显式声明
var cache: [URL: Data] = [:]
let constants: [String: Double] = ["pi": 3.14, "e": 2.718]
三、访问值
let scores = ["张三": 95, "李四": 88, "王五": 70]
// 下标访问(返回 Optional)
scores["张三"] // Optional(95)
scores["赵六"] // nil
// 安全访问
if let score = scores["李四"] {
print(score) // 88
}
// 默认值
let zhao = scores["赵六"] ?? 0
四、修改字典(var)
var mutable = ["A": 1]
// 添加/更新
mutable["B"] = 2
mutable.updateValue(3, forKey: "A") // 返回旧值 Optional(1)
// 删除
mutable["A"] = nil // 返回 nil
mutable.removeValue(forKey: "B") // 返回 Optional(2)
mutable.removeAll()
五、常用属性
属性 说明 .count键值对数量 .isEmpty是否为空 .keys所有键(LazyCollection) .values所有值(LazyCollection)
scores.count // 3
scores.isEmpty // false
Array(scores.keys) // ["张三", "李四", "王五"]
六、遍历字典
for (key, value) in scores {
print("\(key): \(value)分")
}
// 只遍历键
for key in scores.keys {
print(key)
}
// 只遍历值
for value in scores.values {
print(value)
}
七、函数式方法(推荐!)
方法 功能 示例 map转换键值对 dict.map { ($0.key, $0.value * 2) }filter过滤 dict.filter { $0.value > 80 }reduce聚合 dict.reduce(0) { $0 + $1.value }compactMap过滤 nil dict.compactMap { $0.value > 90 ? $0.key : nil }
let highScores = scores.filter { $0.value >= 90 }
let names = scores.map { $0.key }
let total = scores.values.reduce(0, +)
八、字典合并
var dict1 = ["a": 1, "b": 2]
let dict2 = ["b": 3, "c": 4]
// 方式1:for 循环
for (k, v) in dict2 {
dict1[k] = v // b 被覆盖为 3
}
// 方式2:merge(Swift 4.0+)
dict1.merge(dict2) { current, new in new } // 覆盖
dict1.merge(dict2) { $0 + $1 } // 键冲突时相加(需值支持)
九、键必须是 Hashable
// 正确:Int, String, UUID 等
var cache: [String: Data] = [:]
// 错误:结构体未实现 Hashable
struct Point { var x, y: Int }
var points: [Point: String] = [:] // 编译错误
// 正确:扩展 Hashable
extension Point: Hashable {
static func == (lhs: Point, rhs: Point) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
func hash(into hasher: inout Hasher) {
hasher.combine(x)
hasher.combine(y)
}
}
十、嵌套字典
var students: [String: [String: Int]] = [
"张三": ["数学": 95, "英语": 88],
"李四": ["数学": 82, "英语": 90]
]
// 访问
let mathScore = students["张三"]?["数学"] // Optional(95)
十一、安全访问扩展
extension Dictionary {
subscript(safe key: Key) -> Value? {
get { return self[key] }
set {
if let value = newValue {
self[key] = value
} else {
self.removeValue(forKey: key)
}
}
}
}
// 使用
scores[safe: "赵六"] = 75
print(scores[safe: "赵六"]) // Optional(75)
十二、性能优化
场景 推荐做法 频繁插入 reserveCapacity(n)查找性能 键用 String 或 Int 遍历顺序 无序,需排序用 sorted() 去重键 字典天然去重
var bigDict = [Int: String]()
bigDict.reserveCapacity(100_000)
十三、字典转数组
// 键值对数组
let pairs = scores.map { (name: $0.key, score: $0.value) }
// 排序
let sortedByScore = scores.sorted { $0.value > $1.value }
十四、实战项目:简易配置中心
class ConfigCenter {
private var storage: [String: Any] = [:]
func set<T>(_ value: T, forKey key: String) {
storage[key] = value
}
func get<T>(_ key: String, as type: T.Type) -> T? {
return storage[key] as? T
}
func remove(_ key: String) {
storage.removeValue(forKey: key)
}
func printAll() {
for (k, v) in storage {
print("\(k): \(v)")
}
}
}
// 使用
let config = ConfigCenter()
config.set("https://api.com", forKey: "apiURL")
config.set(30, forKey: "timeout")
config.set(true, forKey: "debug")
if let url = config.get("apiURL", as: String.self) {
print("API: \(url)")
}
十五、字典速查表
操作 代码 创建 ["a": 1]添加 dict["b"] = 2删除 dict["a"] = nil长度 .count判空 .isEmpty键集合 .keys值集合 .values遍历 for (k,v) in dict过滤 .filter { }转换 .map { }合并 .merge()安全访问 dict["x"] ?? default
十六、练习题(当场写!)
// 1. 实现字典倒序(按值排序)
func sortedByValue(_ dict: [String: Int]) -> [(String, Int)] {
// 你的代码
}
// 2. 统计字符串中每个字符出现次数
func charFrequency(_ s: String) -> [Character: Int] {
// 你的代码
}
// 3. 实现 groupBy:将数组按条件分组
func groupBy<T, K: Hashable>(_ array: [T], key: (T) -> K) -> [K: [T]] {
// 你的代码
}
答案(展开查看)
点击查看答案
// 1.
func sortedByValue(_ dict: [String: Int]) -> [(String, Int)] {
return dict.sorted { $0.value > $1.value }
}
// 2.
func charFrequency(_ s: String) -> [Character: Int] {
var freq: [Character: Int] = [:]
for c in s {
freq[c, default: 0] += 1
}
return freq
}
// 3.
func groupBy<T, K: Hashable>(_ array: [T], key: (T) -> K) -> [K: [T]] {
return array.reduce(into: [:]) { result, item in
let k = key(item)
result[k, default: []].append(item)
}
}
// 使用示例
let grouped = groupBy([1,2,3,4,5]) { $0 % 2 == towards 0 ? "even" : "odd" }
总结:字典黄金法则
法则 说明 1. 优先用 ["key": value] 字面量 简洁 2. 安全访问用 ?? 默认值 防崩溃 3. 能用函数式就不用循环 map/filter/reduce4. 键用 String 或 Int 性能高 5. 合并用 merge 优雅 6. 嵌套字典访问用可选链 dict["a"]?["b"]
你已完全掌握 Swift 字典!
回复关键词继续学习 :
Swift 字典性能优化
Swift Hashable 协议深入
Swift JSON 解析与字典
SwiftUI @State 与字典绑定
现在就用 reduce(into:) 实现一个 groupBy 函数,将 [1,2,3,4,5] 按奇偶分组!