Swift 4.1/Xcode9.3:字典键值互换的扩展实现问题
把字典键值互换函数改造成Swift Dictionary扩展
嘿,我来帮你搞定这个问题!你已经写出了核心的键值互换逻辑,现在只需要调整一下写法,利用Swift Dictionary的关联类型,就能把它改成优雅的扩展啦。
先看你的原函数(补全后大概是这样)
你的基础函数应该类似下面这样,通过遍历生成新字典:
func swapKeyValues<T, U>(of dict: [T : U]) -> [U : T] { var newDict = [U: T]() for (key, value) in dict { newDict[value] = key } return newDict }
改造成Dictionary扩展的正确写法
Dictionary本身自带Key和Value两个关联类型,所以在扩展里不需要额外声明泛型参数,直接用这两个类型就行:
extension Dictionary { /// 互换字典的键和值(注意:若原字典存在重复值,新字典会保留最后一个对应的键) func swappedKeyValues() -> [Value: Key] { var swappedDict = [Value: Key]() for (key, value) in self { swappedDict[value] = key } return swappedDict } }
处理值重复的场景(重要!)
上面的写法有个小问题:如果原字典里有多个相同的值,作为新字典的键会发生冲突,后面的键会覆盖前面的。如果你想保留所有重复值对应的键,可以把新字典的值类型改成数组,这样更安全:
extension Dictionary { /// 互换键值,保留所有重复值对应的键(值类型为数组) func swappedKeyValuesPreservingDuplicates() -> [Value: [Key]] { var swappedDict = [Value: [Key]]() for (key, value) in self { // 使用default参数简化数组追加逻辑 swappedDict[value, default: []].append(key) } return swappedDict } }
用法示例
// 测试普通互换 let originalDict = ["apple": 1, "banana": 2, "cherry": 1] let swappedDict = originalDict.swappedKeyValues() print(swappedDict) // 输出: [1: "cherry", 2: "banana"] // 测试保留重复值的互换 let swappedWithDuplicates = originalDict.swappedKeyValuesPreservingDuplicates() print(swappedWithDuplicates) // 输出: [1: ["apple", "cherry"], 2: ["banana"]]
为什么这样改可行?
- Dictionary的扩展可以直接访问它的关联类型
Key和Value,不用像普通函数那样手动声明泛型参数T、U - 扩展里的
self就是当前的字典实例,直接遍历self就能拿到所有键值对 - 两种写法分别对应了“只保留最后一个重复值”和“保留所有重复值”的场景,你可以根据需求选择
内容的提问来源于stack exchange,提问作者Noah Wilder
相关产品推荐
相关产品推荐

