Dictionary 初始化器的语法
在 Swift 中,Dictionary 有一种特别的初始化方式,可以从序列(如数组或字典的 map 结果)中生成字典,同时指定如何处理重复的键:
1、uniqueKeysWithValues
Dictionary(uniqueKeysWithValues:) 用于从一个唯一键的键值对序列创建字典。此方法要求序列中的键必须唯一,否则会导致运行时错误。
Dictionary(uniqueKeysWithValues: Sequence)
假设我们有一个元组数组,每个元组包含一个国家代码和国家名称:
let countryPairs = [("US", "United States"), ("FR", "France"), ("JP", "Japan")]
let countryDict = Dictionary(uniqueKeysWithValues: countryPairs)
print(countryDict) // 输出:["US": "United States", "FR": "France", "JP": "Japan"]
在这个例子中,countryPairs 中的键是唯一的,因此转换为字典时不会出现问题。
2、Sequence, uniquingKeysWith
Dictionary(_:uniquingKeysWith:) 用于从一个可能包含重复键的键值对序列创建字典。遇到重复键时,该方法提供一个闭包来决定保留哪一个值。
Dictionary(Sequence, uniquingKeysWith: (Value, Value) -> Value)
假设我们有一个数组,其中包含一些可能重复的键:
let repeatedPairs = [("US", "United States"), ("FR", "France"), ("US", "USA")]
let uniqueCountryDict = Dictionary(repeatedPairs, uniquingKeysWith: { (first, _) in first })
print(uniqueCountryDict) // 输出:["US": "United States", "FR": "France"]
在这个例子中,数组 repeatedPairs 中包含两个 “US” 键。在使用 uniquingKeysWith 闭包时,我们指定 { (first, _) in first },表示在遇到重复键时保留第一个值 (“United States”),丢弃后续的值 (“USA”)。

如果想保留最后出现的值,我们可以写成 { (_, last) in last }:
let uniqueCountryDict2 = Dictionary(repeatedPairs, uniquingKeysWith: { (_, last) in last })
print(uniqueCountryDict2) // 输出:["US": "USA", "FR": "France"]
在这个版本中,字典会保留 “US”: “USA”。
(_, last) 是两个参数:第一个参数 _ 表示先遇到的值,last 表示后遇到的值。
in 关键字之后的内容是闭包的返回值。在这个例子中,last 是闭包的返回值,表示遇到重复键时保留最后一个值。
因此,Dictionary 将 “US” 重复键的值 “USA”(即第二次出现的值)保留在字典中,而丢弃了第一次出现的 “United States”。

3、Dictionary(grouping:by:)
把一个元素数组按照某种规则(闭包)分组成字典。
let names = ["Anna", "Alex", "Brian", "Jack"]
let grouped = Dictionary(grouping: names) { $0.first! }
// grouped 的结果是:["A": ["Anna", "Alex"], "B": ["Brian"], "J": ["Jack"]]
这个例子把字符串数组 names 按照首字母分组,结果就是一个以首字母为 key 的字典。
在实际应用中,可以将Core Data对象按照date分组:
Dictionary(grouping: results, by: { $0.date ?? Date.distantPast })
将查询的Core Data结果results按照date分组,最终的结果为:
[Date: [Eurofxrefhist, Eurofxrefhist]]
Eurofxrefhist是Core Data类型,Date.distantPast是Date的静态属性,表示非常遥远的过去时间。
总结
Dictionary(uniqueKeysWithValues:):用于无重复键的序列,直接创建字典。
Dictionary(_:uniquingKeysWith:):用于可能有重复键的序列,提供闭包来解决冲突。
Dictionary(grouping:){}:用于将元素数组按照某种规则分组成字典,适用于日期等类型分组。
{ (_, last) in last } 保留重复键的最后一个值。
{ (first, _) in first } 保留重复键的第一个值。
这两个闭包只是提供了不同的规则来处理重复键,而 first 和 last 是命名的参数,表示顺序上先遇到和后遇到的值。
相关文章
Swift科普文《字典》:https://fangjunyu.com/2024/10/24/swift%e7%a7%91%e6%99%ae%e6%96%87%e3%80%8a%e5%ad%97%e5%85%b8%e3%80%8b/