Collection Types in Swift

Harshvardhan Arora
5 min readMar 16, 2022
Photo by Jon Tyson on Unsplash

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 Literal
print(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.

--

--