Swift Dictionary default value
This changed in Swift 4, and there's now a way to read a key's value or provide a default value if the key isn't present. For example:
let person = ["name": "Taylor", "city": "Nashville"]
let name = person["name", default: "Anonymous"]
This is particularly useful when modifying dictionary values, because you can write code like this:
var favoriteTVShows = ["Red Dwarf", "Blackadder", "Fawlty Towers", "Red Dwarf"]
var favoriteCounts = [String: Int]()
for show in favoriteTVShows {
favoriteCounts[show, default: 0] += 1
}
I covered this change and others in my article What's new in Swift 4.
Using Swift 2 you can achieve something similar to python's version with an extension of Dictionary
:
// Values which can provide a default instance
protocol Initializable {
init()
}
extension Dictionary where Value: Initializable {
// using key as external name to make it unambiguous from the standard subscript
subscript(key key: Key) -> Value {
mutating get { return self[key, or: Value()] }
set { self[key] = newValue }
}
}
// this can also be used in Swift 1.x
extension Dictionary {
subscript(key: Key, or def: Value) -> Value {
mutating get {
return self[key] ?? {
// assign default value if self[key] is nil
self[key] = def
return def
}()
}
set { self[key] = newValue }
}
}
The closure after the ??
is used for classes since they don't propagate their value mutation (only "pointer mutation"; reference types).
The dictionaries have to be mutable (var
) in order to use those subscripts:
// Make Int Initializable. Int() == 0
extension Int: Initializable {}
var dict = [Int: Int]()
dict[1, or: 0]++
dict[key: 2]++
// if Value is not Initializable
var dict = [Int: Double]()
dict[1, or: 0.0]