Swift 字典

Swift 字典(Dictionary)全解析(2025 版)

“Dictionary 是无序、键值对、Hashable 键” —— 掌握 50+ 操作,写出 高效、安全、函数式 的键值存储代码!


一、Swift 字典核心特性

特性说明
值类型赋值时复制,线程安全
无序插入顺序 ≠ 遍历顺序
唯一键键必须唯一(自动覆盖)
键必须 HashableStringInt 等默认支持
动态大小可增删键值对
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过滤 nildict.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)
查找性能键用 StringInt
遍历顺序无序,需排序用 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/reduce
4. 键用 StringInt性能高
5. 合并用 merge优雅
6. 嵌套字典访问用可选链dict["a"]?["b"]

你已完全掌握 Swift 字典!


回复关键词继续学习

  • Swift 字典性能优化
  • Swift Hashable 协议深入
  • Swift JSON 解析与字典
  • SwiftUI @State 与字典绑定

现在就用 reduce(into:) 实现一个 groupBy 函数,将 [1,2,3,4,5] 按奇偶分组!

文章已创建 2481

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部