[Updated to Swift 2.0 9/10/2015 SJL]
I wrote early in my Swift tutorials a simple example of a dictionary But I really didn’t go too deep into all the ways one can use a dictionary. In this lesson we’ll bring everyone up to speed in using dictionaries, and for those who don’t know what a dictionary is, we’ll introduce them.
What is a Dictionary

Dictionaries and arrays make up the collection types of Swift. Collections are exactly what they say: a collection of values. The difference between an array and a dictionary is how you get the values in and out of the collection. Arrays, as we covered elsewhere, are ordered collections. They have an index which gives their exact place in the collection. I know with an array a value by its position in the array. I know what is before and after my current position by changing the index from its current position. Arrays must use positive integers in sequence to work this magic.
Dictionaries are unordered collections. No one knows which value comes next, and we really don’t care. The power of a dictionary is we have a key, and the key can pretty much be anything we like that’s a unique value. One of the most common keys will be strings, but integers and doubles can certainly be used. Dictionaries look up values by the key.
While in an array we pair an index with a value, we pair a key with a value in a dictionary. In Swift, all keys are the same type and all values are the same type in a given dictionary. The value can be of any type, even other objects or collection types. We call the key, then a value returns. Often we find a syntax of key:value
for dictionary pairs.
In this lesson for most of these examples, we’ll use a playground. Set up a new playground named SwiftDictionary.
How to Declare a Dictionary
The simplest declaration is to let implicit typing do all the work. We declare a variable or constant and list the key:value pairs in square brackets.
let cookies = ["Chocolate Chip":0.25,"Oatmeal":0.26,"Peanut Butter":0.02,"Sugar":0.03]
This would create an unmutable dictionary. We can refer to it, but can not change any value. For a mutable dictionary, we could use this:
var mutableCookies = ["Macadamia Nut":0.06,"Coconut":0.20, "Macaron":0.55]
To help with readability in a long list of values, you can list them on multiple lines like this:
var gelato = [ "Coconut":0.25, "Pistachio":0.26, "Stracciatella":0.02, "Chocolate":0.03, "Peanut Butter":0.01, "Bubble Gum":0.01 ]
You can explicitly type your of key:value pairs. The preferred way to do this is:
let piePrice:[String:Double] = [ "Apple":3.99,"Raspberry":3.35 ]
We specify the types in the key value pair surrounded by square brackets. Here we have a string for the key, and a double for the value. There is another declaration which is available but frowned on by Apple.
let piePrice:Dictionary<string,double> = [ "Apple":3.99,"Raspberry":0.35 ]
This code is identical in function to the previous example but writes out the word Dictionary
and uses the <
and <
characters around the key value pair types.
There are times you need an empty dictionary. In those cases, call the dictionary initializer, which for a dictionary is the key:value pair enclosed in square brackets:
var pieToppings = [String:Double]()
Alternatively, though frowned upon by Apple, you can do this too:
var pizzaSizes = Dictionary<Int, String>()
How to Access a Dictionary
If I wanted to know the price of two slices of pie, the basic syntax is the same for an array, but instead of an index in the square brackets we place the key. We’ve already declared pie prices per slice like this:
let piePrice:[String:Double] = ["Apple":3.99,"Raspberry":0.35]
Like an array’s index, you place the key on brackets:
piePrice["Apple"]
I might write in my code to compute the extend price of pie the following:
let slices = 2.0 let extPrice = piePrice["Apple"]! * slices println("\(slices) of Apple Pie is \(extPrice)")
The code piePrice["Apple"]
returns the price of a slice of apple pie. Notice I wrote piePrice["Apple"]!
, with the forced unwrap optional operator. Returned dictionary values are always optionals. At any given time, I do not know if there is a certain type of pie or not in my dictionary. If I tried piePrice["Coconut Cream"]
I need some way to tell me that there is no coconut cream pies in my dictionary. Type
piePrice["Coconut Cream"]
The playground returns nil
. Swift makes the return value of a dictionary an optional value, so it will return nil
if there is no such entry.
If your dictionary is a constant, you know exactly what’s there. In that case, a forced unwrap like above is fine. If you have a dictionary where you may add or delete elements from the dictionary, make sure you check for nil
.
if piePrice["Apple"] != nil { let extPrice = piePrice["Apple"]! * slices print("\(slices) slices of Apple Pie is \(extPrice)") }
or more compactly with optional chaining
if let price = piePrice["Apple"]{ let extPrice = price * slices print("\(slices) slices of Apple Pie is \(extPrice)") }
If you are not familiar with optionals, refer to the Ten Points for Using Optionals post to get yourself up to speed.
Of course, keys are not always literal. We can use a variable or constant. We can change the code above to include a constant for the gelato type.:
let gelatoType = "Pistachio" if let price = gelato[gelatoType] { let extPrice = price * slices print("\(slices) scoops of " + gelatoType + " is \(extPrice)") }
Change a Dictionary
Suppose we have a dictionary of prices for pizza by a unit area like a square inch, square cm or such. Add this dictionary:
var toppings = ["Pepperoni":0.25, "Sausage":0.26, "Onions":0.02, "Green Peppers":0.03, "Cheese":0.01 ]
Our cost of Sausage and Cheese increases, and we need to change prices in our dictionary. We can change the value with assignment:
toppings["Sausage"] = 0.29 toppings["Sausage"]
Assignment uses subscript syntax and simply changes the value.
toppings.updateValue(0.2, forKey: "Cheese") toppings["Cheese"]
Line 2 uses the updateValue(value:,forKey:)
which does the same as line 1 but the function returns a value. You can write line 2 like this as well:
let oldTopping = toppings.updateValue(0.02,forKey: "Cheese") if oldTopping == nil{ print("Key not found") }
The method returns the value as an optional before we changed it. If there is no key, updateValue(value:,forKey:)
returns nil
. There is a check to tell the developer that this was not in the dictionary. No value is not a fatal error, unlike an array. If we change a value that isn’t there, such as:
let anotherTopping = toppings.updateValue(0.15,forKey: "Gorgonzola") toppings["BBQ Chicken"] = 0.24
Swift will add the new entry to the dictionary. There are times that we may not want to add a new element, but give an error or do something else. Using updateValue(value:,forKey:)
we can check for nil
. If nil
, we execute code to delete the new value and do whatever we need to for an unknown key.
To delete a dictionary entry, you can set its value to nil
:
gelato["Bubble Gum"] = nil gelato
You can also use the removeValueForKey
method
let deletedTopping = gelato.removeValueForKey("Peanut Butter") deletedTopping gelato
The method removeValueforKey(:key)
deletes the element. Like updateValue(value:,forKey:)
the method returns the value deleted. When deleting an element that does not exist, the method tells you by returning nil
, and the subscript syntax does nothing. The rule is simple: If you need to know there was no key present, use the method version.
Iterating Dictionaries
Sometimes we need to list or change everything in a dictionary. You can use the for..in
loop to do that. If you need to print a list of all entries and their values in the toppings
dictionary, create a tuple with identifier names:
for (myKey,myValue) in toppings { print("\(myKey) \t \(myValue)") }
Here we don’t have optionals involved, since all values are existing values. If we need to iterate through just keys or values we can do that using the .keys
or .values
. To list all the values , we could do this:
for myValue in toppings.values{ print ("Value = \(myValue)") }
The iterator myValue
here is a constant inside of the loop. You cannot change this value. For example, if we need to make a 10% increase in prices for our toppings we can’t write:
for myValue in toppings.values{ myValue = myValue * 1.10 }
The compiler would tell us:
Cannot assign to 'let' value 'myValue'
.
We cannot use the values in the for..in
loop to do this. If we want to change values in the loop, we iterate over the keys. Do the calculation directly to the dictionary value based on the iterated key.
//make a 10% price increase for myKey in toppings.keys{ toppings[myKey] = toppings[myKey]! * 1.10 }
Sometimes we need an array of the keys or values, since a particular API requires an array. We can use the .keys
or .values
to create an array:
var valuesArray = [Double](toppings.values) let keyArray = [String](toppings.keys)
Passing a Dictionary as a Parameter
Sometimes you will need to pass a lot of values of the same type in a method through a parameter. Instead of making a dozen parameters, you can store their values in a dictionary.
func myFunction(dictionary:[String:Double],key:String)-> Double?{ return dictionary[key] } myFunction(gelato,key: "Coconut")
While this really does nothing special, it make a good prototype function. You can see how to declare a dictionary in a function. Declare the dictionary like you would in an explicit let
or var
statement. Note here I made the return value Double?
to let the optional value through.
Examples Using a Dictionary
Here’s some examples of a dictionary in use. Let’s look at some code from the PizzaDemo App I created in other lessons. In that earlier post, I stored a price per square inch of pizza as part of a class called Pizza. I can declare a literal dictionary like this in pizza:
var pizzaPricePerInSq = [ "Cheese": 0.03, "Sausage": 0.06, "Pepperoni": 0.05, "Veggie": 0.04 ]
In the Pizza
class I also created a computed property with the array of keys for use with a table view.
var typeList:[String] { get{ return Array(pizzaPricePerInSq.keys) } }
I updated the next example a little bit from the original in PizzaDemo. This demonstrates how to get a value from a dictionary, when you might get a nil
value. Here the price goes to zero if not found.
func unitPrice(pizzaType:String) ->Double{ if let unitPrice = toppings[pizzaType] { return unitPrice } else { return 0.0 } }
I could of course do this as well with optionals and skip the if..else
clause. We would send back nil
instead of 0 and the calling function would deal with an unknown key.
In my UITableview Post I used all of this to make a table view of pizzas and price per square inch.
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? { //note I did not check for nil values. Something has to be really broken for these to be nil. let row = indexPath!.row //get the array index from the index path let cell = tableView!.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath) as? UITableViewCell //make the cell let myRowKey = pizza.typeList[row] //the dictionary key cell.textLabel.text = myRowKey let myRowData = pizza.pizzaPricePerInSq[myRowKey] //the dictionary value cell.detailTextLabel.text = String(format: "%6.3f",myRowData!) return cell }

I used the dictionary starting in the highlighted line 5. Dictionaries are non-ordered, and for an ordered object like a table view, I need something to correspond in an ordered fashion to my table view’s indexPath
. I used the computed property typelist
, which is an array of keys. This is a good way to get a dictionary ordered when needed. Make an array of keys and iterate over the array pointing to the dictionary. In the highlighted Line 7 I take the key and get the price.
We’ve kept the value’s type to something simple. You can declare a value as a class instead. In my pizza ordering system, I could have a class describing a pizza order, and use a key to hold the order number. Often people use sequential numbers for the order number. If so, an array might work there. Some systems hide data in the order number, like the date, time or server ID. Hopefully this was a helpful introduction to Dictionaries in Swift.
The Whole Code
Here is a file of the playground for this lesson. While typing in the code above is very useful you can use this to experiment with dictionaries.
//: Playground - noun: a place where people can play import UIKit //SwiftDictionary //(c)2015 Steven Lipton // declare a unmutable dictionary let cookies = ["Chocolate Chip":0.25,"Oatmeal":0.26,"Peanut Butter":0.02,"Sugar":0.03] //declare a mutable dictionary var mutableCookies = ["Macadamia Nut":0.06,"Coconut":0.20, "Macaron":0.55] //A better way to format your //code for dictionary entries var gelato = [ "Coconut":0.25, "Pistachio":0.26, "Stracciatella":0.02, "Chocolate":0.03, "Peanut Butter":0.01, "Bubble Gum":0.01 ] //Explicit defintion of the key and value let piePrice:[String:Double] = [ "Apple":3.99, "Raspberry":3.35 ] /* use the one above instead let piePrice:Dictionary<string,double> = [ "Apple":3.99,"Raspberry":0.35 ] */ //Two cases of empty dictionary declarations var pieToppings = [String:Double]() var pizzaSizes = Dictionary<Int, String>() //return a value using a key piePrice["Apple"] //Return a value in an expression //note the reurned value is optional //so we have to unwrap it let slices = 2.0 let extPrice = piePrice["Apple"]! * slices print("\(slices) slices of Apple Pie is \(extPrice)") //What happens when a key does not exist? //We get nil piePrice["Coconut Cream"] //Check for nil if piePrice["Apple"] != nil { let extPrice = piePrice["Apple"]! * slices print("\(slices) slices of Apple Pie is \(extPrice)") } //Optional Chaining if let price = piePrice["Apple"]{ let extPrice = price * slices print("\(slices) slices of Apple Pie is \(extPrice)") } //the key as a constant let gelatoType = "Pistachio" if let price = gelato[gelatoType] { let extPrice = price * slices print("\(slices) scoops of " + gelatoType + " is \(extPrice)") } //Making a list of toppings, and then changing values var toppings = ["Pepperoni":0.25, "Sausage":0.26, "Onions":0.02, "Green Peppers":0.03, "Cheese":0.01 ] //Change Sausage to 0.29 toppings["Sausage"] = 0.29 toppings["Sausage"] //Change Cheese to 0.2 toppings.updateValue(0.2, forKey: "Cheese") toppings["Cheese"] //Warn an updated value does not exist let oldTopping = toppings.updateValue(0.02,forKey: "Cheese") if oldTopping == nil{ print("Key not found") } //Actaully that adds a entry to the dictionary. //you can add a entry with the updateValue method too let anotherTopping = toppings.updateValue(0.15,forKey: "Gorgonzola") toppings["BBQ Chicken"] = 0.24 //Deleting an entry in the dictionary //set its value to nil gelato["Bubble Gum"] = nil gelato //Delete a entry using a function let deletedTopping = gelato.removeValueForKey("Peanut Butter") deletedTopping //deleted entry gelato //its gone now //Loop through values and keys for (myKey,myValue) in toppings { print("\(myKey) \t \(myValue)") } //Loop through values for myValue in toppings.values{ print ("Value = \(myValue)") } //make a 10% price increase //with a loop of keys for myKey in toppings.keys{ toppings[myKey] = toppings[myKey]! * 1.10 } //getting an array of keys or values var valuesArray = [Double](toppings.values) let keyArray = [String](toppings.keys) // passing dictionaries through parameters //very useful if you have to pass a lot of values of they same type as one parameter func myFunction(dictionary:[String:Double],key:String)-> Double?{ return dictionary[key] } myFunction(gelato,key: "Coconut")
Leave a Reply