Collection Types in Swift
Swift has three primary collection types — Arrays, Sets and Dictionaries. They provide us with different ways to store similar type of data together. This article covers creating, accessing and modifying these collection type through examples in code. As usual, the promise is minimum theory and maximum code. The entire playground used in this tutorial can be found here!
Arrays
Ordered collection of values which are of same type.
Creating Arrays
var array0 = Array<Int>() // Empty Array
var array1: Array<Int> = [1]
var array2: [Int] = [2]
var array3 = [3] // Array Literal
As seen above, array3 is created via an array literal. Swift automatically infers the type of the array to be of Int. You can now check the type of all the above arrays and see that they all will be the same.
print(type(of: array0)) // Output - Array<Int>
print(type(of: array1)) // Output - Array<Int>
print(type(of: array2)) // Output - Array<Int>
print(type(of: array3)) // Output - Array<Int>
You can also create an array which repeats a single number —
var array4 = Array(repeating: 5.3, count: 3)
print(array4) // Output - [5.3, 5.3, 5.3]
print(type(of: array4)) // Output - Array<Double>
As you can see, the data type of the array is inferred to be Double because you provided a decimal number inside the init(repeating:count:) method.
Note that while creating the above array, you did not call Array.init() method. You will learn about the why in the article for Initialisation in Swift.
You can also combine two arrays —
var array5 = array1 + array2
print(array5) // Output - [1, 2]
Accessing and Modifying Arrays
You can check the number of items in an array or whether it is empty or not.
var shoppingList = ["Milk", "Eggs", "Paint", "Fruits"]
print(shoppingList.count) // Output - 4
print(shoppingList.isEmpty) // Output - false
You can add items to an array.
shoppingList.append("Vegetables")
shoppingList.append(contentsOf: ["Oil", "Shampoo", "Scrub"])
shoppingList += ["Pancake Mix"]print(shoppingList.count) // Output - 9
What you need to be careful of is while using the += operator, the right hand side should contain a array with data type same as the array you are adding it to which for this case will be Array<String>.
You can access and modify an element of the array using subscript syntax.
print(shoppingList[5]) // Output - Oil
shoppingList[5] = "Hair Oil"
print(shoppingList[5]) // Output - Hair Oil
While accessing an element of the array, you need to be careful of the index you are trying to access. If the index does not exist in the array, it would result in a crash.
You can access and modify a range of elements as well.
You can remove elements using the remove(at:) method —
let firstElement = shoppingList.remove(at: 0)
print(shoppingList[0...1]) // Output - ["Maple Syrup", "Bread"]
The remove method also returns back the element it removed from the array.
Iterating over Arrays
for item in shoppingList {
print(item, terminator: " ")
}for (index, item) in shoppingList.enumerated() {
print("Item \(index + 1): \(item)")
}
Sets
Unordered collection of unique values of same type where the type stored should conform to Hashable protocol.
Creating Sets
var set0 = Set<Int>()
var set1: Set<Int> = []
var set2: Set = [1, 2, 3, 4]print(type(of: set0)) // Output — Set<Int>
print(type(of: set1)) // Output — Set<Int>
print(type(of: set2)) // Output — Set<Int>
You cannot create Sets through literals. You need to specify the type of the Set explicitly.
While creating a set from arrays, it automatically removes any duplicate values.
Accessing and Modifying Sets
As seen from the example, the remove() method returns the removed value if it exists otherwise it returns nil.
Iterating over Sets
for items in shoppingListSet {
print(items, terminator: " ")
}for items in shoppingListSet.sorted() {
print(items, terminator: " ")
}
The first loop would print the elements of the set in a random manner. If you run the code repeatedly, it might end up different each time. But the second loop uses the sorted version of the set which would then print the elements in ascending order.
Set Operations
You can perform some standard set operations like union, intersection, symmetric difference and subtraction. You can also check for if a set is a subset, superset or disjoint with another set.
Dictionaries
Unordered collection of key-value pairs where the keys are of the same type and the values are of the same type as well. The keys need to conform to Hashable protocol just like for Sets.
Creating Dictionaries
let dict0 = Dictionary<Int, String>()
let dict1: Dictionary<Int, String> = [:]
let dict2: [Int: String] = [:]
let dict3 = [1: "1"] // Dictionary Literalprint(type(of: dict0)) // Output - Dictionary<Int, String>
print(type(of: dict1)) // Output - Dictionary<Int, String>
print(type(of: dict2)) // Output - Dictionary<Int, String>
print(type(of: dict3)) // Output - Dictionary<Int, String>
You can create a Dictionary via literal as well like you did for dict3.
Accessing and Modifying Dictionaries
var numbers = [
1: "One",
2: "Two",
4: "Four",
7: "Seven",
5: "Five"
]
Accessing the count of key-value pairs —
print(numbers.count) // Output - 5
print(numbers[5]) // Output - Optional("Five")
Note: Accessing the key of a dictionary returns an optional. This ensures that the code will not crash if that key is not found. You will learn more about this in the article for Optionals in Swift.
Updating values —
numbers[9] = "Nine"
let oldNum = numbers.updateValue("Eleven", forKey: 11)
Removing values —
numbers[2] = nil // Removes the key-value pair for key - 2
numbers.removeValue(forKey: 4)
print(numbers.count) // Output - 5
Iterating over Dictionaries
You can iterate over both the key-value pairs together, or individually you can iterate over the keys or the values as well.
Iterating over key-value pair —
for (numberInt, numberString) in numbers {
print("String for \(numberInt) is \(numberString)")
}
Iterating over keys —
for numberInt in numbers.keys {
print(numberInt, terminator: " ")
}
Iterating over values —
for numberString in numbers.values {
print(numberString, terminator: " ")
}
Hashable Protocol
For the time being, you can consider that conforming to Hashable Protocol simply allows a type to compute a hash value for itself that allows the system to easily store and retrieve that value when required.
You will learn about protocols in the article for Protocols in Swift.
All Swift’s basic types like String, Int, Double and Bool are hashable which can be directly used as keys for dictionaries.