In programming, a dictionary is a general-purpose data structure, used to store a group of objects, in a “real” dictionary-like lemma-definition approach - or as group of key-value pairs, properly put.
In this chapter, we’ll explore most of Swift’s dictionary-related capabilities and learn how to create new ones, add/remove keys, merge them, and move on to even more advanced topics, such as handling property lists.
9.1 Add key-value pair to dictionary
Problem
I want to add a key-value pair to an existing dictionary
Solution
Let’s initialize our test dictionary.
var user = [
"name" : "John",
"surname" : "Doe",
]
OK, let’s add some more info.
user["nationality"] = "US"
How It Works
A dictionary is a collection of key-value
pairs. In order to add another key with a value, we can do it pretty much like changing an already existing key, that is: by using the subscript along with the value’s key and assign it the desired value.
User: ["name": "John", "surname": "Doe", "email": "
[email protected]", "nationality": "US"]
9.2 Check if dictionary is empty
Problem
I want to check if a dictionary is empty.
Solution
First, we initialize our example dictionary with some data.
let a = [
"name" : "John",
"surname" : "Doe"
]
Now, let’s see...
if a.isEmpty {
print("Our dictionary is empty :(")
} else {
print("Of course it's not empty - we just created it!")
}
How It Works
To check if a
dictionary is empty, we can use its
isEmpty property.
Of course it's not empty - we just created it!
9.3 Check if key exists in dictionary
Problem
I want to check if a specific key exists in a given dictionary.
Solution
First, we initialize our example dictionary.
var d = [
"name" : "John",
"surname" : "Doe",
]
Now, let’s see...
if d["address"] != nil {
print("Yes, address found!")
} else {
print("Ooops, no address found!")
}
How It Works
To check if a given dictionary
contains a specific key, we may use the dictionary’s
subscript.
9.4 Check if object is dictionary
Problem
I want to check if a given object is of type dictionary.
Solution
First, we initialize our example “object” – let’s make it a dictionary, as expected.
var a : Any = [
"name" : "John",
"surname" : "Doe"
]
Now, let’s see...
if a is [String:String] {
print("Yes, it's a String:String dictionary. Well done!")
} else {
print("Oh, no, this is not a dictionary!")
}
How It Works
To check if an object is of type
dictionary, we can use an
X is a dictionary or
X is [type:type] statement.
Yes, it's a String:String dictionary. Well done!
9.5 Check if two dictionaries are equal
Problem
I want to check if two different dictionaries are equal.
Solution
First, we initialize our dictionaries.
let a = ["name": "John", "surname": "Doe"]
let b = ["name": "Jane", "surname": "Doe"]
Let’s see...
if a == b {
print("Yep, the dictionaries are equal")
} else {
print("Nope, they are different dictionaries")
}
How It Works
To compare two
dictionaries and check if they are equal, we can use the
== comparison operator.
Nope, they are different dictionaries
9.6 Convert dictionary to array of tuples
Problem
I want to convert a given dictionary to an array of key-value tuples.
Solution
First, we initialize an example dictionary.
let fruit = [
"banana" : "yellow",
"apple" : "red",
"watermelon" : "green"
]
Let’s map it to an array of tuples.
let fruitArray = fruit.map { ($0,$1) }
And... print the result.
print("Fruit: (fruitArray)")
How It Works
If we have a
dictionary, we can convert it into an array, by mapping its key-value pairs to tuples using the dictionary’s
map method
.
Fruit: [("watermelon", "green"), ("apple", "red"), ("banana", "yellow")]
9.7 Convert dictionary to JSON string
Problem
I want to convert a dictionary object to its corresponding JSON string representation.
Solution
First, let’s create an example dictionary.
let dict : [String:Any] = [
"name" : "John",
"surname" : "Doe",
"age" : 69
]
// Convert our dictionary to Json data
let json = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
// Convert our Json data to string
let str = String(data: json, encoding: .utf8)
// And if all went well, print it out
print(str ?? "Ooops... Error converting Json to string!")
}
catch let error
{
print("Error: (error)")
}
How It Works
In order to convert a Swift dictionary to JSON, we may use the
JSONSerialization
class.
{
"name" : "John",
"surname" : "Doe",
"age" : 69
}
9.8 Convert JSON string to dictionary
Problem
I want to convert an object represented as a JSON string to a dictionary object.
Solution
First, let’s set some test JSON.
let json = "{"name": "John", "surname": "Doe", "age": 69 }"
Then, we convert it to a
Data object.
if let data = json.data(using: .utf8) {
// if everything went fine,
// it's time to convert our Data object to a Dictionary
let result = try? JSONSerialization.jsonObject(with: data, options: []) as! [String:Any]
// And finally, what about printing out our dictionary?
print(result ?? "Ooops... Error converting Json!")
How It Works
In order to convert a JSON
string to a Swift dictionary, we may use the
JSONSerialization class.
["name": John, "surname": Doe, "age": 69]
9.9 Create a dictionary with literal
Problem
I want to create a dictionary object from a dictionary literal.
Solution
This is a dictionary, with its type automatically inferred.
let a = [
"Country" : "Spain",
"Capital" : "Madrid"
]
This is the same one, but this time let’s set a type, for example, keys of
String type, with values of
String type.
let b : [String:String] = [
"Country" : "Spain",
"Capital" : "Madrid"
]
Let’s create a mixed dictionary with different types of elements. And different types of keys. This is rather tricky.
This time we have to explicitly say it’s of type
[AnyHashable:Any]. Otherwise, the compiler will complain.
let c : [AnyHashable:Any] = [
1 : "one",
"two" : 2
]
Let’s see what we’ve managed...
print("a: (a)")
print("b: (b)")
print("c: (c)")
How It Works
Creating a
dictionary from a dictionary literal is as simple as listing your key-value pairs (with a
: between the two), separated by commas, surrounded by a pair of square brackets.
a: ["Capital": "Madrid", "Country": "Spain"]
b: ["Capital": "Madrid", "Country": "Spain"]
c: [AnyHashable(1): "one", AnyHashable("two"): 2]
9.10 Create an empty dictionary
Problem
I want to create an empty dictionary object .
Solution
First approach: Use the
[:] empty dictionary
expression.
let a : [String:String] = [:]
Second approach: Use a
dictionary constructor.
Third approach: “Enforce” its type with
as.
let c = [:] as [String:Int]
Let’s print our three... empty dictionaries.
print("a: (a), b: (b), c: (c)")
How It Works
In order to create an empty dictionary, it works pretty much as with the
arrays ; the only thing you have to specify is the type of items (keys and values) it’s going to contain.
9.11 Create NSDictionary from dictionary
Problem
I want to create an NSDictionary object from a dictionary.
Solution
First, we initialize our example array with some values.
let dict = [
"name" : "John",
"surname" : "Doe",
]
Let’s convert it to an
NSDictionary.
let b = NSDictionary(dictionary: dict)
Let’s try using the
NSDictionary’s
hash property
(not available for Swift pure dictionaries) to make sure we made it.
print("Final dictionary's hash: (b.hash)")
print("Yep, it's an NSDictionary!")
How It Works
In order to convert/bridge a
dictionary to an NSDictionary, for example, when you need to access APIs that expect data in an
NSDictionary instance, we can use the
NSDictionary(dictionary:) initializer.
Final dictionary's hash: 3
Yep, it's an NSDictionary!
9.12 Get array of keys in dictionary
Problem
I want to get a given dictionary’s keys as an array.
Solution
Let’s initialize our test dictionary.
let dict = [
"name" : "John",
"surname" : "Doe",
]
Then, we get its keys into an array.
let keys = Array(dict.keys)
Let’s print the result...
print("Our dictionary keys: (keys)")
How It Works
A dictionary is a collection of
key-value pairs. But what if we want to get just the keys? For that, we can use the dictionary’s
keys property.
Our dictionary keys: ["name", "surname", "email"]
9.13 Get dictionary value for key
Problem
I want to get the value of a specific key from a given dictionary.
Solution
Let’s initialize our test dictionary.
let user = [
"name" : "John",
"surname" : "Doe",
]
Then, we get the user’s name.
Careful: This is optional; and it is not guaranteed that we’ll find this particular key in the dictionary.
if let userName = user["name"] {
// Let's print the result
print("Our user's name is: (userName)")
How It Works
A dictionary is a collection of key-value
pairs. In order to retrieve a specific value, we may use the
subscript along with the value’s key.
9.14 Get size of dictionary
Problem
I want to get the size of a given dictionary.
Solution
First, we initialize our example dictionary with some date.
let a = [
"name" : "John",
"surname" : "Doe",
]
Now, let’s count how many key-value pairs we’ve got...
print("The dictionary contains (a.count) elements")
How It Works
To check the size of a
dictionary, we can use its
count property.
The dictionary contains 3 elements
9.15 Loop through a Dictionary
Problem
I want to loop through a dictionary, keeping track of each key-value pair.
Solution
Let’s initialize our example dictionary.
let userInfo = [
"name" : "John",
"surname" : "Doe",
]
Let’s iterate through our dictionary...
for (item,value) in userInfo {
print("(item) = (value)")
}
How It Works
Looping through a
dictionary is just as easy as looping through an array. Only we have to keep track of both parts of each pair: key and value.
9.16 Merge two dictionaries
Problem
I want to merge two different dictionaries into a new one.
Solution
First, we initialize our example dictionaries.
var dictA = [ "1" : "one", "2" : "two", "4" : "four" ]
let dictB = [ "1" : "uno", "3" : "tres" ]
Let’s loop through our dictB.
for (key,value) in dictB {
// if key doesn't exist, create it
// if it does exist, update it
Now, let’s print our new dictionary...
How It Works
If we have two dictionaries and
want to merge them, that is: to add one dictionary’s items to another one, updating keys if necessary; there is no built-in method, but we can loop and update the keys/values accordingly.
Merged: ["3": "tres", "2": "two", "1": "uno", "4": "four"]
9.17 Read contents of Plist from file into dictionary
Problem
I want to read the contents of a Property List (Plist) file into a dictionary object.
For example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Books</key>
<array>
<dict>
<key>author</key>
<string>Fyodor Dostoyevsky</string>
<key>title</key>
<string>Crime and Punishment</string>
</dict>
<dict>
<key>author</key>
<string>George Orwell</string>
<key>title</key>
<string>Animal Farm</string>
</dict>
</array>
</dict>
</plist>
Solution
Now, let’s set our Plist
path.
let path = "tests/test.plist"
And read our Plist.
if let data = try? Data(contentsOf: URL(fileURLWithPath: path)) {
var format = PropertyListSerialization.PropertyListFormat.xml
let dict = try? PropertyListSerialization.propertyList(from: data, options: [], format: &format) as! [String : String]
// Finally, we print out the result
print(dict ?? "Error converting Plist")
How It Works
In order to read a property list (XML Plist) string as a dictionary, we may use PropertyListSerialization’s propertyList method
.
9.18 Read contents of Plist from string into dictionary
Problem
I want to read the contents of a Property List (Plist) string into a dictionary object.
Solution
First, we initialize our Plist string.
let plist = "<?xml version="1.0" encoding="UTF-8"?>" +
"<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">" +
"<plist version="1.0">" +
"<dict>" +
"<key>one</key>" +
"<string>value</string>" +
"<key>two</key>" +
"<string>another value</string>" +
"</dict>" +
"</plist>"
Now, let’s read it.
let data = plist.data(using: .utf8)
var format = PropertyListSerialization.PropertyListFormat.xml
let dict = try? PropertyListSerialization.propertyList(from: data!, options: [], format: &format) as! [String : String]
And print out the result...
print(dict ?? "Error converting plist")
How It Works
In order to read a property list (XML Plist)
string as a dictionary, we may use PropertyListSerialization’s
propertyList method
.
["one": "value", "two": "another value"]
9.19 Remove all items from dictionary
Problem
I want to remove all elements from a given dictionary.
Solution
First, we initialize a test dictionary.
var user = [
"name" : "John",
"surname" : "Doe",
]
Then, we remove all of its contents.
Let’s see our new - empty – dictionary...
How It Works
To remove all
values from an existing dictionary (basically: empty it), we may use the dictionary’s
removeAll method.
9.20 Remove dictionary item by key
Problem
I want to remove a specific item from a given dictionary, by its key.
Solution
First, we initialize a test dictionary.
var user = [
"name" : "John",
"surname" : "Doe",
]
Then we delete its name or, literally, remove its values with a
name key.
user.removeValue(forKey: "name")
Let’s see the resulting dictionary...
How It Works
To remove a particular key-value
pair from an existing dictionary, we may use the dictionary’s
removeValue(forKey:) method
.
9.21 Set dictionary value by key
Problem
I want to set the value of a specific key in a given dictionary.
Solution
Let’s initialize our test dictionary.
var user = [
"name" : "John",
"surname" : "Doe",
]
What about changing the user’s name?
How It Works
A dictionary is a collection of
key-value pairs. In order to set a specific value, we may use the subscript along with the value’s key and assign the new value.
9.22 Summary
In this chapter, we learned how we can make use of one of the most powerful constructs in Swift: the dictionary.
In the next chapter, we’ll be looking into more advanced Swift topics: from working with numbers and dates, to interacting with the file system, performing web requests, or even launching system processes.