在 Swift 中,Dictionary
是一组 键值对 的集合,提供了许多接口(方法和属性)来管理和操作字典。Dictionary
的键是唯一的,值可以是任意类型,甚至可以重复。以下是 Dictionary
的常用接口,按功能分类列表并附中文说明及示例。
1. 字典基本信息
#
属性或方法 | 功能说明 | 示例 |
---|
count | 返回字典中键值对的数量。 | print(dict.count) |
isEmpty | 检查字典是否为空,空返回 true 。 | if dict.isEmpty { print("Empty dictionary") } |
keys | 返回字典中所有键的集合(类型为 Dictionary.Keys )。 | let allKeys = dict.keys |
values | 返回字典中所有值的集合(类型为 Dictionary.Values )。 | let allValues = dict.values |
2. 添加和更新
#
方法名称 | 功能说明 | 示例 |
---|
updateValue(_:forKey:) | 更新指定键的值,如果键不存在则添加,返回原来的值(可选类型)。 | let oldValue = dict.updateValue(30, forKey: "age") |
subscript(_:) | 通过键访问或设置字典的值,如果键不存在则添加新键值。 | dict["name"] = "Alice"; let value = dict["name"] |
3. 删除
#
方法名称 | 功能说明 | 示例 |
---|
removeValue(forKey:) | 删除指定键对应的值,返回被删除的值(如果不存在,返回 nil )。 | let removedValue = dict.removeValue(forKey: "age") |
removeAll() | 删除字典中所有键值对,字典变为空。 | dict.removeAll() |
4. 查询操作
#
方法名称 | 功能说明 | 示例 |
---|
contains(where:) | 检查字典中是否有键值对满足指定条件。 | let exist = dict.contains(where: { $0.key == "name" }) |
first(where:) | 返回第一个满足条件的键值对(可选类型)。 | let result = dict.first(where: { $0.value == "Alice" }) |
keys.contains(_:) | 检查字典是否包含指定键。 | if dict.keys.contains("name") { print("Key exists") } |
5. 合并
#
方法名称 | 功能说明 | 示例 |
---|
merging(_:uniquingKeysWith:) | 合并两个字典,指定冲突时的键值处理逻辑,返回新字典。 | let result = dict.merging(newDict) { old, new in new } |
merge(_:uniquingKeysWith:) | 原地合并两个字典,指定冲突时的键值处理逻辑。 | dict.merge(newDict) { (_, new) in new } |
6. 遍历
#
方法名称 | 功能说明 | 示例 |
---|
forEach(_:) | 遍历字典中的所有键值对,执行闭包中的操作。 | dict.forEach { print("\($0.key): \($0.value)") } |
map(_:) | 对每个键值对进行映射,返回包含转换结果的新数组。 | let result = dict.map { $0.key + ":" + "\($0.value)" } |
filter(_:) | 筛选满足条件的键值对,返回新的字典。 | let filtered = dict.filter { $0.value as? Int ?? 0 > 20 } |
7. 数据提取与变换
#
方法名称 | 功能说明 | 示例 |
---|
compactMapValues(_:) | 对字典值进行映射,并移除返回 nil 的键值对。 | let newDict = dict.compactMapValues { Int($0) } |
mapValues(_:) | 对字典的每个值进行映射,返回修改后的新字典。 | let modified = dict.mapValues { "\($0)!" } |
reduce(_:_:) | 将字典中的所有键值对组合计算成一个值。 | let result = dict.reduce(0) { $0 + ($1.value as? Int ?? 0) } |
8. 默认值访问(防止键不存在问题)
#
方法名称 | 功能说明 | 示例 |
---|
subscript(_:default:) | 如果键存在则返回对应值,否则返回指定的默认值。 | let value = dict["name", default: "No Name"] |
9. 字典操作(创建、更新、合并)
#
创建字典
#
方法 | 功能说明 | 示例 |
---|
使用字典字面量 | 使用简单的键值对字面量创建字典。 | let dict: [String: Int] = ["age": 25, "score": 100] |
使用 init(uniqueKeysWithValues:) | 使用键值对数组自动生成字典,键不能重复。 | let dict = Dictionary(uniqueKeysWithValues: [("key1", "value1"), ("key2", "value2")]) |
字典合并
#
用法 | 功能说明 | 示例 |
---|
合并字典 | 合并多个字典,冲突时指定处理逻辑。 | let result = dict1.merging(dict2, uniquingKeysWith: { oldValue, newValue in newValue }) |
10. Swift 5.7+ 特性
#
新增方法 | 功能说明 | 示例 |
---|
grouping(_:by:) | 根据指定的分组规则,将数组转化为字典,以指定条件分组键值。 | let grouped = Dictionary(grouping: [1, 2, 3, 4, 5], by: { $0 % 2 }) |
Dictionary(_:uniquingKeysWith:) | 通过键值对直接生成字典,冲突时指定处理逻辑。 | let dict = Dictionary([("a", 1), ("b", 2)], uniquingKeysWith: max) |
11. 类型检查和比较
#
方法名称 | 功能说明 | 示例 |
---|
== | 比较两个字典内容是否完全相同(键值对一一匹配)。 | if dict1 == dict2 { print("Equal") } |
keys.sorted() | 按键排序并返回排序后的键集合。 | let sortedKeys = dict.keys.sorted() |
基础获取方法
#
1. 使用下标语法(最常用)
#
let capitals = ["France": "Paris", "Italy": "Rome", "Japan": "Tokyo"]
// 获取值(返回可选类型)
if let paris = capitals["France"] {
print("法国的首都是 \(paris)") // 输出: 法国的首都是 Paris
}
// 获取不存在的键
let london = capitals["UK"] // london 为 nil
2. 使用 subscript(_:default:)
方法(Swift 4+)
#
// 提供默认值
let ukCapital = capitals["UK", default: "London"]
print(ukCapital) // 输出: London
// 计算出现次数
let words = ["apple", "banana", "apple", "orange"]
var wordCounts = [String: Int]()
for word in words {
wordCounts[word, default: 0] += 1
}
print(wordCounts) // 输出: ["apple": 2, "banana": 1, "orange": 1]
高级获取方法
#
3. 使用 first(where:)
方法
#
// 查找第一个符合条件的键值对
if let firstCapital = capitals.first(where: { $0.key == "Italy" }) {
print("意大利的首都是 \(firstCapital.value)") // 输出: 意大利的首都是 Rome
}
4. 使用 keys
和 values
属性
#
// 获取所有键
let countries = capitals.keys
print(countries) // 输出: ["France", "Italy", "Japan"]
// 获取所有值
let cities = capitals.values
print(cities) // 输出: ["Paris", "Rome", "Tokyo"]
5. 使用 filter
方法
#
// 过滤符合条件的键值对
let asianCountries = capitals.filter { country, capital in
country == "Japan" || country == "China"
}
print(asianCountries) // 输出: ["Japan": "Tokyo"]
安全获取模式
#
6. 可选绑定(推荐)
#
if let italyCapital = capitals["Italy"] {
print("意大利的首都是 \(italyCapital)")
} else {
print("未找到意大利的首都信息")
}
7. 空合运算符(Nil-Coalescing Operator)
#
let germanyCapital = capitals["Germany"] ?? "Berlin"
print(germanyCapital) // 输出: Berlin
8. 使用 guard let
语句
#
func printCapital(for country: String) {
guard let capital = capitals[country] else {
print("未找到 \(country) 的首都信息")
return
}
print("\(country) 的首都是 \(capital)")
}
printCapital(for: "France") // 输出: France 的首都是 Paris
printCapital(for: "Canada") // 输出: 未找到 Canada 的首都信息
字典键值获取的最佳实践
#
1. 避免强制解包
#
❌ 不推荐:
let rome = capitals["Italy"]! // 如果键不存在会崩溃
✅ 推荐:
if let rome = capitals["Italy"] {
// 安全使用
}
2. 使用 default
参数简化代码
#
// 旧方法
var scores = ["Alice": 5, "Bob": 3]
scores["Alice"] = (scores["Alice"] ?? 0) + 1
// 新方法(Swift 4+)
scores["Alice", default: 0] += 1
3. 处理不存在的键
#
// 使用空合运算符
let score = scores["Charlie"] ?? 0
// 使用字典的默认值方法
let defaultValue = scores["Charlie", default: 0]
4. 使用键路径(Swift 5.2+)
#
struct Country {
var name: String
var capital: String
}
let countries = [
"FR": Country(name: "France", capital: "Paris"),
"IT": Country(name: "Italy", capital: "Rome")
]
// 使用键路径获取值
if let italyCapital = countries["IT"]?.capital {
print(italyCapital) // 输出: Rome
}
完整示例:国家首都查询系统
#
import Foundation
struct CapitalCitySystem {
private var capitals: [String: String]
init() {
capitals = [
"France": "Paris",
"Italy": "Rome",
"Japan": "Tokyo",
"Germany": "Berlin",
"Spain": "Madrid",
"China": "Beijing",
"India": "New Delhi",
"Brazil": "Brasília",
"Australia": "Canberra",
"Canada": "Ottawa"
]
}
func getCapital(for country: String) -> String? {
capitals[country]
}
func getCapitalWithDefault(for country: String) -> String {
capitals[country, default: "未知"]
}
func searchCapitals(containing searchText: String) -> [String: String] {
capitals.filter { country, capital in
country.localizedCaseInsensitiveContains(searchText) ||
capital.localizedCaseInsensitiveContains(searchText)
}
}
mutating func addCapital(country: String, capital: String) {
capitals[country] = capital
}
mutating func removeCapital(for country: String) {
capitals[country] = nil
}
func printAllCapitals() {
for (country, capital) in capitals.sorted(by: { $0.key < $1.key }) {
print("\(country): \(capital)")
}
}
}
// 使用示例
var system = CapitalCitySystem()
// 查询首都
if let franceCapital = system.getCapital(for: "France") {
print("法国的首都是 \(franceCapital)")
}
// 使用默认值查询
let russiaCapital = system.getCapitalWithDefault(for: "Russia")
print("俄罗斯的首都是 \(russiaCapital)") // 输出: 俄罗斯的首都是 未知
// 添加新首都
system.addCapital(country: "Russia", capital: "Moscow")
print(system.getCapital(for: "Russia") ?? "未找到") // 输出: Moscow
// 搜索功能
let searchResults = system.searchCapitals(containing: "a")
print("包含 'a' 的国家/首都:")
for (country, capital) in searchResults {
print("- \(country): \(capital)")
}
// 删除首都
system.removeCapital(for: "Brazil")
print(system.getCapital(for: "Brazil") ?? "巴西信息已删除") // 输出: 巴西信息已删除
// 打印所有首都
print("\n所有国家及其首都:")
system.printAllCapitals()
总结
#
在 Swift 中获取字典键值有多种方式:
- 下标语法:最常用方式,返回可选值
- default 参数:提供默认值,避免可选类型
- 可选绑定:安全解包可选值
- 空合运算符:提供默认值的简洁方式
- 高阶函数:如
filter
, first(where:)
等
最佳实践:
- 优先使用可选绑定或空合运算符处理可能不存在的键
- 使用
default
参数简化计数和累加操作 - 避免强制解包,防止运行时崩溃
- 使用键路径访问嵌套字典中的值
通过合理选择获取方式,可以编写出既安全又高效的 Swift 代码。
常用代码示例
#
1. 合并两个字典
#
var dict1 = ["name": "Alice", "age": 25]
let dict2 = ["age": 30, "city": "New York"]
dict1.merge(dict2) { (_, new) in
return new
}
// dict1 = ["name": "Alice", "age": 30, "city": "New York"]
2. 筛选字典中满足条件的键值对
#
let dict = ["A": 10, "B": 20, "C": 15, "D": 5]
let filteredDict = dict.filter { $0.value > 10 }
// filteredDict = ["B": 20, "C": 15]
3. 设置默认值时访问字典
#
let dict = ["name": "Alice"]
let age = dict["age", default: "Not specified"] // age = "Not specified"
4. 创建一个分组的字典
#
let array = [1, 2, 3, 4, 5, 6]
let grouped = Dictionary(grouping: array, by: { $0 % 2 })
// grouped = [0: [2, 4, 6], 1: [1, 3, 5]]
5. 提取不为 nil
的键值(compactMapValues
)
#
let dict = ["key1": "123", "key2": "abc", "key3": "456"]
let numberDict = dict.compactMapValues { Int($0) }
// numberDict = ["key1": 123, "key3": 456]
6. 查找最小/最大值的键值对
#
let dict = ["A": 10, "B": 20, "C": 15]
let maxPair = dict.max(by: { $0.value < $1.value })
// maxPair = ("B", 20)
总结
#
Swift 的 Dictionary
提供了强大的键值对管理接口,支持高效的添加、删除、查找和筛选,常用接口包括:
增删改:
- 添加:
updateValue(_:forKey:)
, merge(_:uniquingKeysWith:)
- 删除:
removeValue(forKey:)
, removeAll()
数据提取与遍历:
- 获取:
keys
, values
- 遍历:
forEach(_:)
, map(_:)
查询操作:
- 检查键值对存在性:
contains(where:)
, keys.contains(_:)
数据变换:
- 筛选:
filter(_:)
- 值映射:
mapValues(_:)
, compactMapValues(_:)