Leonardo Maia Pugliese
Holy Swift

Holy Swift

Default Value from Dictionary in Swift

Default Value from Dictionary in Swift

The subscript magic

Leonardo Maia Pugliese's photo
Leonardo Maia Pugliese

Published on Jun 16, 2021

4 min read

Subscribe to my newsletter and never miss my upcoming articles

Hallo vrienden, Leo hier.

Today we'll discuss some interesting and somewhat kind confusing default value getter from dictionaries. Using dictionaries in Swift are easy and straightforward but when you come across some not so usual situations, things may be confusing. So stay tuned for this tip and let's code!

But first...

The Painting

The painting chosen was 1932 called Old Books from Catherine Mary Wood. She was a British painter and unfortunately with a very little info about her online.

The painting was chosen because dictionaries were books in the old days :)

The problem

You want to when get value from a dictionary if you don't find any, you have a default value from it.

Imagine do you have a dictionary with name and age of a person, you can initialize it in various ways:

var nameAgeDict: Dictionary<String,Int> = [:]
var nameAgeDict2: [String:Int] = [:]
var nameAgeDict3 = [String:Int]()
var nameAgeDict4 = Dictionary<String,Int>()
var nameAgeDict5 = ["Leo":30]
var nameAgeDict6: Dictionary<String,Int> = Dictionary<String,Int>()

Once you initialized it, you can set new key and values:

nameAgeDict["Tales"] = 12

You can print it resulting in:

Screen Shot 2021-06-16 at 08.38.49.png

But what if you want to check if a person exists and if not add that person to the dictionary with a default value? You can use the default parameter of the Dictionary subscript like this:

for name in ["Leo","Ana","John"] {
    nameAgeDict[name] = nameAgeDict[name,default: -1]
}

Now the print statement will be:

Screen Shot 2021-06-16 at 08.44.08.png

Great! Now we have default values when are sure to have all the names into our dictionary. Now let's dive a little deeper into this syntax.

With the subscript default parameter you sure have a value for a key. This also can be used with the += function to count thinks individually, like how many of each letter are in some string:

let message = "Hello my friends, how are you doing?!"
var letterCounts: [Character: Int] = [:]
for character in message {
    letterCounts[character, default: 0] += 1 // mark 1
}

print("\n")
print(letterCounts)

The mark one means: Search for the character in the dictionary. If you find add one to it, if not use the default value plus one and create an entry in the dictionary with the character being the key.

Resulting in a neatly separated dictionary, notice that whitespaces are considered too:

Screen Shot 2021-06-16 at 09.00.57.png

One curious thing about the subscript default parameter is that work magically with the += and -= functions/operator. Analyze the code below:

nameAgeDict["Tales", default: 0] += 1 // mark 1
nameAgeDict["Tales"] = nameAgeDict["Tales", default: 0] + 1 // mark 2

The result of both statements are the same. Mark 1 was already explained. But if mark 1 works... How can mark 2 work as well? What is the real return of the subscript default parameter?

    @inlinable public subscript(key: Key, default defaultValue: @autoclosure () -> Value) -> Value

So the return is the Value in our case is Int... but wait... now the mark 1 doesn't make sense. If the return of the subscript is a value, the += function should at most sum zero to one how does it knows it should create a dictionary entry for the Key provided if the result of the subscript is a Value?

Well, this I couldn't find an answer. If anyone reading this know how and why the mark 1 and mark 2 works instead of the "compiler magic" response please leave a comment below.

Summary

That's it. Today we've explored some details and behaviors of dictionary default subscript and also some "add and assign" magic.

That's all my people, I hope you liked as I enjoyed write this article. If you want to support this blog you can Buy Me a Coffee or just leave a comment saying hello. You can also sponsor posts and I'm open to writing freelancing! Just reach me in LinkedIn or Twitter for details.

Thanks for the reading and... That's all folks.

credits: image

Did you find this article valuable?

Support Leonardo Maia Pugliese by becoming a sponsor. Any amount is appreciated!

Learn more about Hashnode Sponsors
 
Share this