There’s no direct way to map the values in a dictionary to create a new dictionary.
You can pass a dictionary itself into map
, since it conforms to SequenceType
. In the case of dictionaries, their element is a key/value pair:
// double all the values, leaving key unchanged
map(someDict) { (k,v) in (k, v*2) }
But this will result in an array of pairs, rather than a new dictionary. But if you extend Dictionary
to have an initializer that takes a sequence of key/value pairs, you could then use this to create a new 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]
The other downside of this is that, if you alter the keys, you cannot guarantee the dictionary will not throw away certain values (because they keys may be mapped to duplicates of each other).
But if you are only operating on values, you could define a version of map
on the values only of the dictionary, in a similar fashion, and that is guaranteed to maintain the same number of entries (since the keys do not change):
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 }
In theory, this means you could do an in-place transformation. However, this is not generally a good practice, it’s better to leave it as creating a new dictionary, which you could always assign to the old variable (note, there’s no version of map
on arrays that does in-place alteration, unlike say sort
/sorted
).