Chapter 7: Dictionaries

Similar to a Swift array, dictionaries are a convenient way of cataloging information. They are super useful if you need to store data with two related values (i.e. word and definition).


What you will learn

  • Creating your first dictionary
  • Adding an item to the dictionary
  • Accessing the amount Of items in a dictionary
  • Checking to see if a dictionary is empty
  • Overriding a dictionary value to modify it
  • Iterating through a dictionary
  • Clearing out a dictionary of all data

Key Terms

  • dictionary: a collection type in Swift 3 which allows for the storing of data in a key-value pair.
  • Key: a unique identifier that is associated with a value.
  • Value: a value which is identified and linked to a unique key.

When you were in school, you were probably asked at one point to look up the definition of a word to determine it's meaning. You knew that the words were sorted alphabetically, so you could efficiently track down the general location of the word, then fine-tune your search as you flipped through a couple pages as you got closer to your target word.

Once you had found your target word, you would read the definition and use that in whatever assignment you were working on.

In Swift, a dictionary (called hash tables or hash maps in other programming languages) is a collection type which associates a key with a value similarly to how a dictionary for a language associates words with their definition.

Swift Dictionaries operate just like a language dictionary does. You start with a key of some type (String, Int, Double, etc.) and a value of the same or a different type. While the value per key can vary, each key in a dictionary must be unique.

The thing that makes them unique is that they are much more efficient to search through than an Array and they are much easier to find particular items. An Array in Swift orders items numerically, which is great in some circumstances, but if you want to find a specific piece of information a dictionary is better. You can associate a key with a value so you can track down the item by it's key – just like you would in a language dictionary.

Let's dive into creating a dictionary in Swift now.

Setting up

First, open Xcode if you haven't already and click Create New Playground. Give it a name like Dictionaries and click Next. Choose somewhere to save this .playground file and click Create to save it. You should see a screen like the one in Figure 1.7.1.

Figure 1.7.1 Screen Shot 2016-10-10 at 5.01.11 AM.png

Delete all the boilerplate code on the left side but leave import UIKit as it is necessary.

Creating your first dictionary

To create your first Swift dictionary, create a variable called namesOfIntegers like so:

var namesOfIntegers = [Int: String]()

What we have done above is declared a variable and called it namesOfIntegers. We've set it to be equal to a Dictionary as indicated by the square brackets. Inside, we have declared that the key type should be Int and the value type should be String.

This means that any data we try to add to this dictionary has to adhere to that rule. We also declared this as an empty dictionary as indicated by the parentheses following the dictionary brackets.

You should see the following print out in the console indicating that we successfully created an empty dictionary (there are no values, but brackets and a colon in the middle):

[:]

Adding an item to the dictionary

A dictionary is no use if it is empty! Let's add some data so that it is a bit more useful to us.

Type the following on a new line beneath the variable namesOfIntegers:

var namesOfIntegers = [Int: String]()

namesOfIntegers[3] = "Three"

You might be thinking, "Hey! That's just like an Array! 3 must be the index and "Three" must be the data that's stored! While that is a fair assumption at the moment, you will soon see how a dictionary is quite different.

The number 3 is actually the name of the key (of type Int) in our dictionary and the value associated with it is a String with a value of "Three".

We added a new key called 3 with a value of "Three". These key-value pairs are what make Dictionaries in Swift so powerful.

Let's add another key and value pair to our dictionary. Add the following at the bottom of your Playground file:

var namesOfIntegers = [Int: String]()

namesOfIntegers[3] = "Three"
namesOfIntegers[44] = "Forty Four"

The thing to note here is that it does not matter at what order you add these values. We access the items in a dictionary by their key not their number order.

Another dictionary example

Let's pretend for a moment that we're building an app that monitors and keeps track of important flight data for all the world's airports. Each airport should definitely have it's own unique code separating if from the others.

If Stockholm, Los Angeles, and Dubai all shared the same airport code, LAX, it would cause a massive amount of confusion and headache all the time.

Luckily, each airport has a unique airport code so that they are all differentiated from one another. A few airports could actually have the same name as long as their code was unique.

The thing about Dictionaries in Swift is that every key must be unique. This is so that all of the data you want to save into it can be differentiated and easily accessed just like each airport code needs to be easily accessible and quickly understood.

Continuing with this example, let's create a dictionary for a list of airport codes. Add the following dictionary at the bottom of your Playground:

...

var airports: [String: String] = ["YYZ": "Toronto Pearson", "LAX": "Los Angeles International"]

OK, cool. So what is happening here? We created a variable called airports and explicitly declared it as a dictionary of type [String: String]. We used the assignment operator (=) and added a pair of square brackets. Inside, we created two key-value pairs.

For each pair, we added a key of type String for each airport code followed by a colon (:). We then added a value of type String containing the airports name. Since we created two key-value pairs, we used a comma to separate the values just like we would in an Array.

Accessing the amount of items in a dictionary

In order to access the amount of items in our dictionary, we can use the same function we do with Arrays. Let's print out a String and pass in the airports.count to show how many airports we've added to our dictionary. Like so:

var airports: [String: String] = ["YYZ": "Toronto Pearson", "LAX": "Los Angeles International"]

print("The airports dictionary has: \(airports.count) items.")

In the console, you should see the following: "The airports dictionary has: 2 items." This should seem familiar from our chapter on Arrays like I said above. Arrays and Dictionaries both share this ability – to count their total number of objects.

Checking to see if a dictionary is empty

We can also look to see if we have any values at all. Use the built in function isEmpty to check this:

...

if airports.isEmpty {
    print("The airports dictionary is empty!")
}

Since we have two items in our dictionary nothing will print. If you were to remove everything from the dictionary, this String would print out in the console.

Overriding a dictionary value to modify it

Let's add a new value to our airports dictionary. At the bottom of your Playground, add the following:

airports["PDX"] = "Portland"

We have now added a new key-value pair, but what if you want to update the value to something different. To override the value we just set all we need to do is change it like so:

airports["PDX"] = "Portland"
airports["PDX"] = "Portland International"

Now, the old value "Portland" is gone and the current value for the key "PDX" is "Portland International". Easy as that!

Removing an item from our dictionary

Let's add a new imaginary airport with a key of "DEV" and a value of "Devslopes International""

...

airports["DEV"] = "Devslopes International"

To remove this item completely from our dictionary, all we need to do is the following:

swift
airports["DEV"] = "Devslopes International"
airports["DEV"] = nil

Now our key-value pair of "DEV": "Devslopes International" is gone forever from our dictionary.


Helpful Hint: nil is used to declare an empty value in Swift. We haven't used nil at all at this point in the book, but know that it is used to set a value to be empty and sometimes is used in removing values from collection types.


Iterating through a dictionary

We can use a for-in loop to do something with the keys and values in our dictionary. Let's make one now! Add the following loop at the bottom of the Playground window:

...

for (airportCode, airportName) in airports {

}

Now, before we write any code inside of our loop let's talk about what we're doing here.

Since a dictionary works under the condition of key and value together, we need to loop through both values simultaneously. Thus, we have the tuple.

Here is how Apple's Swift 3 documentation defines a tuple: "Tuples group multiple values into a single compound value. The values within a tuple can be of any type and do not have to be of the same type as each other."

We are doing just what the definition describes when we loop through our dictionary. We combine the airport code and the airport name into a singular compound value and can modify it as we please.

Using both Key and Value

Let's put our tuple to use. Inside the for-in loop, add the following:

for (airportCode, airportName) in airports {
    print("\(airportCode): \(airportName)")
}

In the console below, you should see the following print out:

LAX: Los Angeles International
YYZ: Toronto Pearson
LHR: London Heathrow

Using only Keys from a dictionary

If we only wanted to print the airport codes (the keys in our dictionary), all we need to do is create another for-in loop and access the keys property of our dictionary like so:

for key in airports.keys {
    print("Key: \(key)")
}

After writing that code, you will see the following print out in the console:

Key: LAX
Key: YYZ
Key: LHR

Any dictionary's keys can be accessed this way. Pretty cool! But so can the values. Check it out below!

Using only Values from a dictionary

We can do the same thing as above, but for the inverse – the values inside our dictionary.

Create another for-in loop to demonstrate this:

for value in airports.values {
    print("Value: \(value)")
}

The following will print out in the console:

Value: Los Angeles International
Value: Toronto Pearson
Value: London Heathrow

Clearing out a dictionary of all data

To clear out your dictionary, you can simply set it to be equal to an empty dictionary. Like so:

namesOfIntegers = [:]

This will reset and clear out all data from our dictionary.

Wrapping up

Dictionaries are super powerful and can be used in a ton of different ways. I personally think dictionaries are a super cool feature of Swift and programming in general. It is a much more orderly and efficient way to organize data when you want to be able to access that data by a key and value pair. Arrays are great and have their place, but Dictionaries are much more versatile in their everyday use.

You will especially use Dictionaries when you get into the later chapters that guide you to build apps that pull data from API servers online. The data is stored in a format called JSON (JavaScript Object Notation) which largely relies on Arrays and Dictionaries for storing and organizing information.

For example, the screenshot below (Figure 1.7.2) is from SWAPI.co (The Star Wars API – amazing, right? 🤘). If you look closely you'll notice data encapsulated inside of curly {} and square [] brackets (Figure 1.7.3).

The curly brackets indicate Arrays and the square brackets indicate Dictionaries. Make sure that you understand both Arrays and Dictionaries well because it can be confusing navigating through JSON calls like the one below. Sometimes, depending on the API, data will be downloaded in a simple Array or dictionary. But for some APIs, the data is more complex and can be stores in Arrays of Dictionaries.

Figure 1.7.2 Screen Shot 2016-10-24 at 5.49.14 PM.png

Figure 1.7.3

Screen Shot 2016-10-24 at 5.50.59 PM.png

Knowing the subtle differences between the two will make all the difference when building those later apps. If you still feel confused, it's always a good idea to read Apple's documentation on Swift 3. Learning to read documentation is an important part of becoming a developer. Don't overlook that!

Nicely done on completing this chapter! Let's move on. 🏃

Exercise

Create a Dictionary called movieReleaseYears that stores the title and year of release for three movies you love. The title of the movie is the key and the release year is the value. Write a for-in loop to pass in the movie titles and release years together and print them both, IMDb-style (i.e. "Toy Story (1995)")