bcardarella
(Brian Cardarella)
1
If I have a dictionary such as:
let book: [AnyHashable:Any] = [:]
Is there a way to have any keys that are accessed that don't have a value to return a default value and not nil ?
cukr
2
print(book["key", default: "Unknown"])
1 Like
Lantua
3
If you're not editing the dictionary, I'd prefer
book[.init("key")] ?? "Default Value"
@Lantua, do you mean that you’d prefer coalescing over @cukr‘a suggestion? If so, why?
Lantua
5
Well, the two codes are identical, so the choice is more of a stylistic one.
Nonetheless, I do prefer ?? over library-specific API since it's what people are more familiar with. One can grok what subscript(_:default:) does, but it's easy to miss that the getter does not write back the default value to the storage (and there are instances of that being a bug IME). If anything, I do use the subscript when there's a write-back involved.
bjhomer
(BJ Homer)
6
If you're only reading a value, then the two alternatives are identical. However, if you're modifying a value in the dictionary, they are not.
For example, this code:
var scoresForUser: [User: Array<Int>] = [:]
func addScore(_ score: Int, for user: User) {
if let existingArray = scoresForUser[user] {
var newArray = existingArray
newArray.append(score)
scoresForUser[user] = newArray
} else {
scoresForUser[user] = [score]
}
}
can be dramatically simplified by using the default: subscript, as shown here:
var scoresForUser: [User: Array<Int>] = [:]
func addScore(_ score: Int, for user: User) {
scoresForUser[user, default:[]].append(score)
}
Because the default value is part of the subscript, you can call a mutating func on it and it will update the dictionary correctly.
But if you're just reading a value, then there's no difference between using subscript(_:default:) and just ?? on the outside.
1 Like