The Swift dictionary is another very useful type of collection in Swift. Like arrays (which you can read more about in my post Arrays and their Methods in Swift), you access them via subscripts usually. Unlike Swift arrays though, these subscripts accept many more values besides Ints. There are some limitations, but it nonetheless gives you a lot more capability than arrays if you need they key used to look it up to be something other than a number. We will also go over some of the methods for dictionaries as well, but there are not nearly as many as for arrays.
Swift Dictionary Command Quick Reference
Here is a table that lists and explains major methods and related syntax for Swift dictionaries. Some of these are pretty self explanatory (like count or isEmpty), and were already gone over in the array post. If you see some of these not covered and you want to know more, you can take a look at my previous post Arrays and their Methods in Swift. We will go over the others a bit more in depth afterwards.
Title | Example | Description |
Dictionary Shorthand Type | [String : Double] | This is used when explicitly declaring the type of the dictionary. This example is a type for a dictionary that has Strings for keys, and Doubles for values. |
Dictionary Literal | [“Regular” : 3.85, “Premium” : 4.15, “Diesel” : 4.09] | This is a shorthand way to generate a dictionary of known objects. The keys and values must be the same type respectively, but the key and value type do not have to be the same. |
Initialize Empty Dictionary | [String : Double]() | This initializes an empty Dictionary that has Strings for keys, and Doubles for values. |
Empty Dictionary Literal | [:] | This initializes an empty dictionary. The dictionary must have its type explicitly (initializing) or previously stated (emptying existing dictionary). |
Subscript Syntax | gasPrices[“Regular”] | The standard way to retrieve a value from a dictionary. This example retrieves the value with the String key of “Regular”. Returns an optional of the value type, containing nil if the value is not present. |
Number of Elements | gasPrices.count | This returns an Int of how many values are in the dictionary. |
isEmpty Shorthand | gasPrices.isEmpty | This returns a Bool describing whether the dictionary is empty or not. If count is 0, this returns true, otherwise it will return false. |
Update Value For Key | gasPrices.updateValue(4.00, forKey: “Regular”) | This updates the value for the key “Regular.” It then returns the previous value that it is supplanting, which is nil if there was no value for that key. |
Remove Value For Key | gasPrices.removeValue(forKey: “Diesel”) | This will remove the value for the key “Diesel.” Like Update Value For Key, it will return the previous value it is removing, which is nil if the value did not exist in the first place. |
Remove All Values | gasPrices.removeAll() | Removes all values from dictionary. Can take a Bool for keepCapacity to not change capacity value. If omitted, defaults to false and sets capacity to 0. |
Iterate Over Dictionary | for (gasType, gasPrice) in gasPrices | This iterates over the dictionary, and assigns the keys to the first variable in the tuple, and the value to the second variable in the tuple. |
Get Collection of Keys | gasPrices.keys | This returns a collection that can be iterated through of the keys of this dictionary. It is not an array. |
Get Collection of Values | gasPrices.values | This returns a collection that can be iterated through of the values of this dictionary. It is not an array. |
There are a few more, but I highly doubt you will be wanting the internal index that a dictionary uses. It might be useful for a quick lookup, but other than that, since the order of values is not guaranteed, it seems like a comparatively unhelpful couple of methods.
Creating a Swift Dictionary
Like Swift arrays, you can create your dictionaries using either initializers or literals, as demonstrated below:
var literalDictionary = ["Breakfast" : "Cereal", "Lunch" : "Sandwich", "Dinner" : "Pizza"] var emptyDictionary = [String : String]()
We first used a literal to create a dictionary that had Strings for keys and Strings for values. We then used an initializer to create an empty dictionary of the same type. Afterwards, I cleared that dictionary again, using an empty dictionary literal. The dictionary literal and type syntax is of the style [Key: Value]. For the type syntax used in the initializer, you just place the type of the key on the left, and the type of the value on the right. For the literal, each element of the dictionary is written that way, with the key object on the left of the colon, and the value object on the right side of the colon. If you want additional values, you just separate each of these groupings with a comma, like we did in the example above about different meals. For the literal, you can have different types for the keys and values, but all of the keys must be of the same type, and all of the values must be of the same type.
Much like the array, the above used type syntax is actually just a better looking form of the dictionary’s actual type, which is Dictionary<String, String>. You can use this if you want, but the square-bracketed form is significantly more readable than this one, so it is preferred. Internally, a Swift dictionary is (like the array), a struct, meaning that it is a value type, and assigning it to a new variable copies it, and does NOT point to the same instance of a dictionary.
You can see the empty dictionary literal in action in my previous post Custom Subscripts in Swift. I felt that it was about time to cover it more officially.
Updating Dictionary Values
You would normally update a value by simple setting to it via subscript notation. You would remove a key from the dictionary by updating it to a value of nil. Both of these styles are shown below:
literalDictionary["Dinner"] = "Salad" literalDictionary["Breakfast"] = nil //Never do this, breakfast is the most important meal of the day!
Swift also provides you with an additional set of methods to do the same thing, but with a twist. You could also use these methods:
let replacedValue = literalDictionary.updateValue("Salad", forKey: "Dinner") let removedValue = literalDictionary.removeValue(forKey: "Breakfast")
What these two methods do, is return an optional of the value that was just updated. This lets you compare what you set to what was there, to see if anything actually was changed. You could updateValue to nil to remove the value, but it just seems a bit easier to just use a method that does that automatically for whatever key you give it.
Dictionary Keys must be Hashable
You can use any type as a value for a Swift dictionary. However, for the fast lookup, all keys must be hashable. The built in Swift types like Int, Double, and String are hashable, and usually the best way to make a custom class hashable, is to change it into one of those and hash it. I found a very good example of how to do this in Swift at Kirby Shabaga’s blog How to implement Hashable for your custom class — Swift Coder. It shows you how to adopt the Hashable protocol and still works as of the current version of Xcode mentioned in the conclusion of this page. In that post, the custom class is a customized CGPoint. The gist of making it hashable, is implementing the Hashable protocol, and then making a string of the X and Y coordinates, getting the hashValue of that String, and returning that as the hashValue of the custom type.
Conclusion
While there are not nearly as many methods for the Swift dictionary type, I thought it would be useful to have them in a quick, easy to reference table. This of course is also available in Apple’s iBook, but in a much longer format. Again, I only covered newer concepts in this post, and many of the ones I covered are extremely analogous to their counterparts for arrays, so you can find more information about most of the ones I did not cover in my post Arrays and their Methods in Swift.
I hope you found this article helpful. If you did, please don’t hesitate to share this post on Twitter or your social media of choice, every share helps. Of course, if you have any questions, don’t hesitate to contact me on the Contact Page, or on Twitter @CodingExplorer, and I’ll see what I can do. Thanks!