Dictionaries
While dictionaries are not as commonly used as arrays, they have an additional functionality that makes them incredibly powerful. A dictionary is a container that stores multiple key-value pairs, where all the keys are of the same type, and all the values are of the same type. The key is used as a unique identifier for the value. A dictionary does not guarantee the order in which the key-value pairs are stored since we look up the values by the key, rather than by the index of the value.
Dictionaries are good for storing items that map to unique identifiers, where the unique identifier should be used to retrieve the item. As an example, countries with their abbreviations are a good example of items that can be stored in a dictionary. In the following chart, we show countries with their abbreviations as key-value pairs:
Creating and initializing dictionaries
We can initialize a dictionary using a dictionary literal similar to how we initialized an array with the array literal. The following example shows how to create a dictionary using the key-value pairs in the preceding chart:
let countries = ["US":"United States","IN":"India","UK":"United Kingdom"]
The preceding code creates an immutable dictionary that contains each of the key-value pairs in the preceding chart. Just like the array, to create a mutable dictionary, we will use the var
keyword rather than the let
keyword. The following example shows how to create a mutable dictionary containing the countries:
var countries = ["US":"United States","IN":"India","UK":"United Kingdom"]
In the preceding two examples, we created a dictionary where the key and value were both strings. The compiler inferred that the key and value were strings because that was the type of values we put in. If we wanted to create an empty dictionary, we would need to tell the compiler what the key and value types are. The following examples create various dictionaries with different key-value types:
var dic1 = [String:String]() var dic2 = [Int:String]() var dic3 = [String:MyObject]()
Note
If we want to use a custom object as the key in a dictionary, we will need to make our custom object conform to the Hashable protocol from Swift's standard library. We will discuss protocol and classes in Chapter 5, Classes and Structures, but, for now, just understand that it is possible to use custom objects as a key in a dictionary.
Accessing dictionary values
We use the subscript syntax to retrieve the value for a particular key. If the dictionary does not contain the key we are looking for, the dictionary will return nil; therefore, the variable returned from this lookup is an optional variable. The following example shows how to retrieve a value from a dictionary using its key in the subscript syntax:
let countries = ["US":"United States", "IN":"India","UK":"United Kingdom"] var name = countries["US"]
In the preceding code, the variable name will contain the string United States
.
Counting key/values in a dictionary
We use the count
method of the dictionary to get the number of key-value pairs in the dictionary. The following example shows how to use the count
method to retrieve the number of key-value pairs in the dictionary:
let countries = ["US":"United States", "IN":"India","UK":"United Kingdom"]; var cnt = countries.count //cnt contains 3
In the preceding code, the cnt
variable will contain the number 3
, since there are three key-value pairs in the countries
dictionary.
Is the dictionary empty?
To test whether the dictionary contains any key-value pairs at all, we can use the isEmpty
method. The isEmpty
method will return false if the dictionary contains one or more key-value pairs and true if it is empty. The following example shows how to use the isEmpty
method to determine whether our dictionary contains any key-value pairs.
let countries = ["US":"United States", "IN":"India","UK":"United Kingdom"] var empty = countries.isEmpty
In the preceding code, the empty
variable is false since there are three key-value pairs in the countries dictionary.
Updating the value of a key
To update the value of a key in a dictionary, we can either use the subscript syntax or the updateValue(forKey:)
method. The updateValue(forKey:)
method has an additional feature that the subscript syntax doesn't—it returns the original value associated with the key prior to changing the value. The following example shows how to use both the subscript syntax and the updateValue(forKey:)
method to update the value of a key:
var countries = ["US":"United States", "IN":"India","UK":"United Kingdom"] countries["UK"] = "Great Britain" //The value of UK is now set to "Great Britain" var orig = countries.updateValue("Britain", forKey: "UK") //The value of UK is now set to "Britain" and orig now contains "Great Britain"
In the preceding code, we use the subscript syntax to change the value associated with the key UK
from United Kingdom
to Great Britain
. The original value of United Kingdom
was not saved prior to replacing it, so we are unable to see what the original value is. We then used the updateValue(forKey:)
method to change the value associated with the key UK
from Great Britain
to Britain
. With the updateValue(forKey:)
method, the original value of Great Britain
is assigned to the orig
variable prior to changing the value in the dictionary.
Adding a key-value pair
To add a new key-value pair to a dictionary, we can use the subscript syntax, or we can use the same updateValue(forKey:)
method that we used to update the value of a key. If we use the updateValue(forKey:)
method and the key is not currently present in the dictionary, the updateValue(forKey:)
method will add a new key-value pair and return nil. The following example shows how to use the subscript syntax, and also the updateValue(forKey:)
method to add a new key-value pair to a dictionary:
var countries = ["US":"United States", "IN":"India","UK":"United Kingdom"] countries["FR"] = "France" //The value of "FR" is set to "France" var orig = countries.updateValue("Germany", forKey: "DE") //The value of "DE" is set to "Germany" and orig is nil
In the preceding code, the countries
dictionary starts with three key-value pairs and we then add a fourth key-value pair (FR/France
) to the dictionary using the subscript syntax. We then use the updateValue(forKey:)
method to add a fifth key-value pair (DE/Germany
) to the dictionary. The orig
variable is set to nil because the countries dictionary did not contain a value associated with the DE
key.
Removing a key-value pair
There may be times when we need to remove values from a dictionary. We can do this with the subscript syntax, using the removeValueForKey()
method, or the removeAll()
method. The removeValueForKey()
method returns the value of the key prior to removing it. The removeAll()
method removes all elements from the dictionary. The following example shows how to use the subscript syntax, the removeValueForKey()
method, and the removeAll()
method to remove key-value pairs from a dictionary:
var countries = ["US":"United States", "IN":"India","UK":"United Kingdom"]; countries["IN"] = nil //The "IN" key/value pair is removed var orig = countries.removeValueForKey("UK") //The "UK" key value pair is removed and orig contains "United Kingdom" countries.removeAll() //Removes all key/value pairs from the countries dictionary
In the preceding code, the countries
dictionary starts off with three key-value pairs. We then set the value associated with the key IN
to nil, which removes the key-value pair from the dictionary. We use the removeValueForKey()
method to remove the key associated with the UK
key. Prior to removing the value associated with the UK
key, the removeValueForKey()
method saves the value in the orig
variable. Finally, we use the removeAll()
method to remove all the remaining key-value pairs in the countries dictionary.