Mastering Swift
上QQ阅读APP看书,第一时间看更新

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.