字典 #

一、字典概述 #

字典是一种存储键值对的无序集合,每个键唯一对应一个值。

1.1 字典特点 #

  • 无序集合
  • 键唯一
  • 键值对存储
  • 值类型(复制时创建副本)

二、创建字典 #

2.1 空字典 #

swift
var emptyDict: [String: Int] = [:]
var emptyDict2 = [String: Int]()
var emptyDict3 = Dictionary<String, Int>()

print(emptyDict.isEmpty)

2.2 字典字面量 #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]
let ages: [String: Int] = ["Tom": 25, "Jerry": 30]

print(scores)
print(ages)

2.3 从数组创建 #

swift
let names = ["张三", "李四", "王五"]
let scores = [90, 85, 95]

let dict = Dictionary(uniqueKeysWithValues: zip(names, scores))
print(dict)

2.4 分组创建 #

swift
let words = ["apple", "banana", "cherry", "apricot", "blueberry"]

let grouped = Dictionary(grouping: words) { String($0.first!) }
print(grouped)

三、访问元素 #

3.1 通过键访问 #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]

print(scores["张三"] ?? 0)
print(scores["赵六"] ?? "不存在")

3.2 安全访问 #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]

if let score = scores["张三"] {
    print("张三的分数是: \(score)")
}

if let score = scores["赵六"] {
    print("赵六的分数是: \(score)")
} else {
    print("赵六不存在")
}

3.3 字典属性 #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]

print(scores.count)
print(scores.isEmpty)

print(Array(scores.keys))
print(Array(scores.values))

3.4 获取键值对 #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]

for (name, score) in scores {
    print("\(name): \(score)分")
}

四、修改字典 #

4.1 添加/更新元素 #

swift
var scores = ["张三": 90, "李四": 85]

scores["王五"] = 95
print(scores)

scores["张三"] = 92
print(scores)

let oldValue = scores.updateValue(88, forKey: "李四")
print("旧值: \(oldValue ?? 0)")
print(scores)

4.2 删除元素 #

swift
var scores = ["张三": 90, "李四": 85, "王五": 95]

scores["李四"] = nil
print(scores)

let removed = scores.removeValue(forKey: "张三")
print("删除的值: \(removed ?? 0)")
print(scores)

scores.removeAll()
print(scores)

4.3 合并字典 #

swift
var scores = ["张三": 90, "李四": 85]
let newScores = ["王五": 95, "张三": 92]

scores.merge(newScores) { (_, new) in new }
print(scores)

五、遍历字典 #

5.1 遍历键值对 #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]

for (name, score) in scores {
    print("\(name): \(score)分")
}

5.2 遍历键 #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]

for name in scores.keys {
    print(name)
}

5.3 遍历值 #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]

for score in scores.values {
    print(score)
}

5.4 排序遍历 #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]

for (name, score) in scores.sorted(by: { $0.key < $1.key }) {
    print("\(name): \(score)分")
}

for (name, score) in scores.sorted(by: { $0.value > $1.value }) {
    print("\(name): \(score)分")
}

六、字典操作 #

6.1 map #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]

let descriptions = scores.map { "\($0.key): \($0.value)分" }
print(descriptions)

6.2 mapValues #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]

let grades = scores.mapValues { score in
    switch score {
    case 90...100: return "A"
    case 80..<90: return "B"
    case 70..<80: return "C"
    default: return "D"
    }
}
print(grades)

6.3 filter #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]

let highScores = scores.filter { $0.value >= 90 }
print(highScores)

6.4 compactMapValues #

swift
let strings = ["a": "1", "b": "2", "c": "three"]

let numbers = strings.compactMapValues { Int($0) }
print(numbers)

6.5 reduce #

swift
let scores = ["张三": 90, "李四": 85, "王五": 95]

let totalScore = scores.reduce(0) { $0 + $1.value }
print(totalScore)

let averageScore = Double(totalScore) / Double(scores.count)
print(averageScore)

七、字典与JSON #

7.1 字典转JSON #

swift
import Foundation

let user: [String: Any] = [
    "name": "张三",
    "age": 25,
    "scores": [90, 85, 95]
]

if let jsonData = try? JSONSerialization.data(withJSONObject: user),
   let jsonString = String(data: jsonData, encoding: .utf8) {
    print(jsonString)
}

7.2 JSON转字典 #

swift
import Foundation

let jsonString = """
{"name":"张三","age":25,"scores":[90,85,95]}
"""

if let jsonData = jsonString.data(using: .utf8),
   let dict = try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any] {
    print(dict)
    print(dict["name"] ?? "")
}

7.3 使用Codable #

swift
import Foundation

struct User: Codable {
    let name: String
    let age: Int
    let scores: [Int]
}

let user = User(name: "张三", age: 25, scores: [90, 85, 95])

if let jsonData = try? JSONEncoder().encode(user),
   let jsonString = String(data: jsonData, encoding: .utf8) {
    print(jsonString)
}

if let decoded = try? JSONDecoder().decode(User.self, from: jsonData) {
    print(decoded)
}

八、实际应用 #

8.1 统计词频 #

swift
let text = "the quick brown fox jumps over the lazy dog the fox"
let words = text.split(separator: " ")

var wordCount: [String: Int] = [:]
for word in words {
    wordCount[String(word), default: 0] += 1
}

for (word, count) in wordCount.sorted(by: { $0.value > $1.value }) {
    print("\(word): \(count)")
}

8.2 缓存 #

swift
class Cache {
    private var storage: [String: Any] = [:]
    
    func set<T>(_ value: T, forKey key: String) {
        storage[key] = value
    }
    
    func get<T>(_ key: String) -> T? {
        return storage[key] as? T
    }
    
    func remove(_ key: String) {
        storage.removeValue(forKey: key)
    }
    
    func clear() {
        storage.removeAll()
    }
}

let cache = Cache()
cache.set("Hello", forKey: "greeting")
let greeting: String? = cache.get("greeting")
print(greeting ?? "")

8.3 配置管理 #

swift
struct Config {
    private var settings: [String: Any] = [
        "timeout": 30,
        "retryCount": 3,
        "debugMode": false
    ]
    
    func get<T>(_ key: String) -> T? {
        return settings[key] as? T
    }
    
    mutating func set<T>(_ key: String, value: T) {
        settings[key] = value
    }
}

var config = Config()
let timeout: Int? = config.get("timeout")
print(timeout ?? 0)

8.4 分组数据 #

swift
struct Student {
    let name: String
    let grade: String
    let score: Int
}

let students = [
    Student(name: "张三", grade: "A", score: 90),
    Student(name: "李四", grade: "B", score: 85),
    Student(name: "王五", grade: "A", score: 95),
    Student(name: "赵六", grade: "B", score: 80)
]

let groupedByGrade = Dictionary(grouping: students) { $0.grade }
for (grade, students) in groupedByGrade {
    print("\(grade)班: \(students.map { $0.name })")
}

九、字典扩展 #

9.1 获取或设置默认值 #

swift
extension Dictionary {
    subscript(key: Key, default defaultValue: @autoclosure () -> Value) -> Value {
        get {
            return self[key] ?? defaultValue()
        }
        set {
            self[key] = newValue
        }
    }
}

var scores: [String: Int] = ["张三": 90]
print(scores["李四", default: 0])
scores["李四", default: 0] += 5
print(scores)

9.2 合并多个字典 #

swift
extension Dictionary {
    static func + (lhs: Dictionary, rhs: Dictionary) -> Dictionary {
        var result = lhs
        result.merge(rhs) { (_, new) in new }
        return result
    }
}

let dict1 = ["a": 1, "b": 2]
let dict2 = ["c": 3, "d": 4]
let combined = dict1 + dict2
print(combined)

十、总结 #

本章学习了Swift字典:

  • 创建:字面量、初始化器
  • 访问:通过键访问、可选绑定
  • 修改:添加、更新、删除
  • 操作:map、filter、reduce

最佳实践:

  • 使用可选绑定安全访问
  • 使用mapValues转换值
  • 合理使用默认值
  • 使用Codable处理JSON

下一章,我们将学习集合!

最后更新:2026-03-26