Swift Dictionary
- Swift Dictionary is a collection of key-value pair elements. They are an unordered list of values of the same type with unique keys. Under the hood, they are just HashTable.
- Hashtable is a data structure composed of Arrays and a hash function, to say the least.
- They are very useful when you need to search for something from large data. In such cases Arrays, LinkedList would consume more time typically with the complexity of O(N) or O(logN). This is where Hashtable is useful as they can return you the search result within O(1) time normally.
- How are the books in your library arranged so that you can find your favorite book easily? How do you search a word in your dictionary? The answer is Hashtables. They use a hash function to convert the data into a simpler one such that you can easily trace the value from the key.
- Swift Dictionaries are value types. Not reference types.
Creating a dictionary
The following dictionary we initialize has the key of type String and value of type Int
import Foundation var countryCodes = [String: Int]() countryCodes["India"] = 91 countryCodes["UAE"] = 971 print(countryCodes.keys) //prints ["India", "UAE"] print(countryCodes.values) //[91, 971]
In the above code, we initialize the dictionary in square brackets. The key is on the left of the colon and the value is on the right. The above is the shorthand syntax. The full syntax of a dictionary is:
[quote font=”georgia”]let dictionary:Dictionary<KeyType, ValueType> = [:][/quote]
Alternatively, we can define a dictionary like:
import Foundation var dictionary = ["Swift" : "iOS", "Java" : "Android" , "Kotlin" : "Android", "Obj-c": "iOS"] print(dictionary["Swift"] as Any) //Optional("iOS") print(dictionary["Kotlin"] as Any) //Optional("Android")
Swift infers the type of the Dictionary as <String, String>. If a key doesn’t exist, it returns nil. To remove a key we just need to set the value to nil.
Swift Dictionary Properties and Functions
- removeAll()method is used to clear the contents of a dictionary.
- count property is used to get the number of key-value pairs.
- isEmpty returns the boolean which tells whether the dictionary is empty or not.
- first returns the first element(key/value pair of the dictionary).
- removeValue(forKey: ) removes the value at the specified key. The value can be stored in a variable/constant.
We can call keys and values property on a dictionary to get the array of keys and values respectively.
import Foundation var countryCodes = [String: Int]() countryCodes["India"] = 91 countryCodes["UAE"] = 971 print(countryCodes) //prints ["UAE": 971, "India": 91] print(countryCodes.first!) //prints (key: "UAE", value: 971) let returnedValue = countryCodes.removeValue(forKey: "USA") countryCodes.removeAll() print(countryCodes.count) //prints 0 print(countryCodes.isEmpty) //prints true print(countryCodes) //prints : [:]
Iterating over a Swift Dictionary
To iterate over a Dictionary in Swift, we use Tuple and a for-in loop.
import Foundation var countryCodes = [String: Int]() countryCodes["India"] = 91 countryCodes["UAE"] = 971 countryCodes["US"] = 1 for (key,value) in countryCodes { print("key is \(key) and value is \(value)") }
[quote font=”georgia”]Since dictionaries are not ordered, you can’t predict the order of iteration.[/quote]
Creating a Dictionary from two arrays
We’ve converted Swift Dictionary to Swift Array to get keys and values array. Now let’s merge two arrays to create a dictionary.
import Foundation let keys = ["August", "Feb", "March"] let values = ["Leo", "Pisces", "Pisces"] let zodiacDictionary = Dictionary(uniqueKeysWithValues: zip(keys,values)) print(zodiacDictionary) //["Feb": "Pisces", "March": "Pisces", "August": "Leo"]
[quote font=”georgia”]zip creates a sequence of pairs built out of two underlying sequences.[/quote]
Handling Duplicate Keys
What if we reverse the keys and values in the above code. It’ll have duplicate keys. Let’s look at how to handle duplicate keys using zip.
import Foundation let zodiacs = ["Leo", "Pisces", "Pisces", "Aries"] let repeatedKeysDict = Dictionary(zip(zodiacs, repeatElement(1, count: zodiacs.count)), uniquingKeysWith: +) print(repeatedKeysDict) //["Leo": 1, "Aries": 1, "Pisces": 2]
- The dictionary is of the type [String: Int]
- The value for each key is incremented if there are repeatable elements with the default value set to 1.
- The above code indirectly gets the number of occurrences of each word.
Dictionary Filtering and Mapping
Swift 4 has given rise to filtering and mapping functions on a Dictionary as shown below.
import Foundation let zodiacs = ["Leo", "Pisces", "Pisces", "Aries"] let repeatedKeysDict = Dictionary(zip(zodiacs, repeatElement(1, count: zodiacs.count)), uniquingKeysWith: +) let filtered = repeatedKeysDict.filter { $0.value == 1 } print(filtered) //prints ["Aries": 1, "Leo": 1] let mapped = filtered.mapValues{"Occurence is \($0)"} print(mapped) //prints ["Aries": "Occurence is 1", "Leo": "Occurence is 1"]
- $0.values gets the current value in the filter.
- $0 gets the current value in mapValues
One Response