如何使用map在Swift中转换字典?

时间:2015-04-05 18:26:04

标签: swift

我有一本字典,我希望转换每个项目的值,但保留原始字典。这就是我想要做的事情:

var someDict = [
  "a": 1,
  "b": 2,
  "c": 3
]

func convert(value: Int) -> [String: Int] {
  return someDict.map({
      item in ????
  }
}

然后我试图最终得到这个:

convert(10) // Result: ["a":10, "b":20, "c":30]
convert(20) // Result: ["a":20, "b":40, "c":60]
convert(5) // Result: ["a":5, "b":10, "c":15]
someDict // Result: ["a":1, "b":2, "c":3]

我不清楚documentation的语法或者map是否正确。任何帮助或建议将不胜感激!

1 个答案:

答案 0 :(得分:6)

没有直接的方法来映射字典中的值来创建新字典。

您可以将字典本身传递到map,因为它符合SequenceType。在字典的情况下,它们的元素是键/值对:

// double all the values, leaving key unchanged
map(someDict) { (k,v) in (k, v*2) }

但是这将产生一对数组,而不是一个新的字典。但是如果你扩展Dictionary以获得一个带有一系列键/值对的初始化器,那么你可以使用它来创建一个新的字典:

extension Dictionary {
    init<S: SequenceType where S.Generator.Element == Element>
        (_ seq: S) {
            self.init()
            for (k,v) in seq {
                self[k] = v
            }
    }
}

let mappedDict = Dictionary(map(someDict) { (k,v) in (k, v*2) })
// mappedDict will be [“a”:2, “b”:4, “c”:6]

另一个缺点是,如果你改变键,你不能保证字典不会丢弃某些值(因为它们的键可能映射到彼此的重复)。

但是如果你只是在操作值,你可以用类似的方式在字典的值上定义map的版本,并且保证保持相同数量的条目(因为键不会改变):

extension Dictionary {
    func mapValues<T>(transform: Value->T) -> Dictionary<Key,T> {
        return Dictionary<Key,T>(zip(self.keys, self.values.map(transform)))
    }
}

let mappedDict = someDict.mapValues { $0 * 2 }

理论上,这意味着您可以进行就地转换。但是,这通常不是一个好习惯,最好将其保留为创建一个新字典,您可以随时将其分配给旧变量(注意,在就地更改的数组上没有map的版本,不像说sort / sorted)。