Dictionary
In Swift 5.8 a dictionary is a primary collection type that can store typed keys and values. We add pairs with assignment.
To safely get a value, we can use if-let
—this syntax is called optional binding. And we can loop over the dictionary with a for
-loop.
This program creates an empty dictionary. It has String
keys and Int
values—this is specified in the type. It adds 3 keys and values with assignment.
nil
—it exists.Int
returned by the dictionary lookup by placing an exclamation mark at its end.// Create a dictionary with String keys and Int values. var weights = [String: Int]() // Add three pairs to the dictionary. weights["cat"] = 8 weights["dog"] = 30 weights["horse"] = 1100 // Look up value in dictionary and see if it exists. let result = weights["cat"] if result != nil { print("Weight is \(result!)") }Weight is 8
A dictionary can be filled through assignment statements. But an initializer expression requires less code. Here we create another String
key, Int
value dictionary.
Optional
binding means we can directly access the Int
.// Create a constant dictionary. // ... It has String keys and Int values. // ... Initialize it with three pairs. let lookup: [String: Int] = ["Swift": 10, "Python": 5, "Java": 3] // Look up the value for Swift key. if let value = lookup["Swift"] { print(value) }10
We vary the types of keys and values. This dictionary uses String
keys and String
values—a common pattern in programs. It caches capitalized strings.
// This dictionary uses String keys and String values. var capitalized = [String: String]() // Add some data to the dictionary. capitalized["dog"] = "DOG" capitalized["bird"] = "BIRD" // Look up a String value. if let result = capitalized["dog"] { print(result) }DOG
For
-in loopSometimes we want to loop over all the pairs (tuples) in a dictionary. We use a for-in
loop here. In each tuple, we have the key and the value.
// Create a String to Int dictionary. var colors = [String: Int]() colors["blue"] = 10 colors["red"] = 40 colors["magenta"] = 20 // Loop over all pairs in the Dictionary. // ... Order is not maintained. for (color, code) in colors { print("Color is \(color), code is \(code)") }Color is red, code is 40 Color is magenta, code is 20 Color is blue, code is 10
Keys
A dictionary has a list of keys. Often in programs we use the keys in a dictionary—the values are not always relevant. We loop over the result of the keys property.
let multipliers: [Int: Int] = [10: 20, 30: 60, 90: 180] // Loop over and display all keys. for key in multipliers.keys { print(key) }30 10 90
Here we initialize another dictionary. We then create a String
array based on the dictionary's values property.
sizesArray
) as any other array. We append another element to it.let sizes: [Int: String] = [1: "Small", 10: "Medium", 50: "Large"] // Convert values of dictionary into a String array. var sizesArray = [String](sizes.values) // Add another String. sizesArray.append("Huge") print(sizesArray)["Large", "Small", "Medium", "Huge"]
Count
A dictionary has a number of key and value pairs. The count property returns this number. It provides a count of pairs—which is the same as key count or value count.
let pages: [String: Int] = ["Index": 0, "About": 10] // Use count property to get number of pairs in dictionary. if pages.count == 2 { print(true) }true
UpdateValue
This func
changes the value for a key in a dictionary. If the key does not exist, a new value is added. If the key is present, the value is altered at that key.
var pages: [String: Int] = ["Index": 0, "About": 10] // Add or update values in the dictionary. pages.updateValue(200, forKey: "Index") pages.updateValue(300, forKey: "Changes") // Display contents. for (key, value) in pages { print(key, value) }About 10 Changes 300 Index 200
RemoveValue
This func
eliminates a pair in a dictionary. With forKey
we specify the key we want to remove. And the value and the key are both erased.
removeValue
with the forKey
argument. The "About" key no longer exists.var pages: [String: Int] = ["Index": 0, "About": 10, "Updates": 20] // Remove this key. pages.removeValue(forKey: "About") // Display dictionary. print(pages)["Updates": 20, "Index": 0]
Contains
keyIn Swift, a nil
value in a dictionary means there is no value. So to determine if a key exists, we just test its value for nil
. If nil
, the key does not exist.
nil
.// Create a dictionary with strings and Ints. // ... Nil values mean "does not exist." var colorIds = [String: Int]() colorIds["blue"] = 1 colorIds["red"] = 2 colorIds["yellow"] = 3 colorIds["orange"] = nil // Detect whether the dictionary contains this string. if colorIds["blue"] != nil { print("Dictionary contains value") } // A nil value means the key does not exist. if colorIds["magenta"] == nil { print("Not found 1") } // This key was assigned nil. // ... This means it does not exist. if colorIds["orange"] == nil { print("Not found 2") }Dictionary contains value Not found 1 Not found 2
It is possible to increment and decrement the values in a dictionary. We must use the question mark to access the optional value (which may not exist).
nil
(on a key that does not exist) nothing will happen. No key will be added.var freqs = ["cat": 10, "dog": 20] // Use optional syntax to increment value. freqs["cat"]? += 1 // Decrement value. freqs["dog"]? -= 1 // A nonexistent key will not cause an error. // ... No value will be added. freqs["bird"]? += 1 freqs["bird"]? += 2 // Cat and dog were modified. print(freqs)["cat": 11, "dog": 19]
A dictionary can be passed as an argument to a func
. We specify the type of the keys and the values. In Swift we use a ":" to begin a type description.
String
keys and Double
values to a validate func
. A guard statement ensures the dictionary has data.func validate(stocks: [String: Double]) { // Ensure at least one pair in dictionary. guard stocks.count >= 1 else { print("Error") return } // Dictionary is valid. print("OK") } // Create a String, Double dictionary. var stocks = ["ABC": 10.99, "XYZA": 9.24] validate(stocks: stocks) // ... This will not print OK. validate(stocks: [String: Double]())OK Error
A dictionary can be placed inside another collection like an array. With an array of dictionaries, we can store more complex data in a simple way.
Sort
The keys and values in a dictionary cannot be directly sorted. But we can take the keys (or values) from the collection and place them in a list, sorting that.
Suppose we need to lowercase many strings, and many values will be repeated. We can use a dictionary to memoize (cache) the result. This can improve performance.
This generic collection is powerful. With dictionaries, we can make lookups faster. Often for optimization, changing an array to a dictionary is effective.