Arrays and dictionaries
Lists that keep order, keyed lookups, and the four tools that work on a whole collection at once.
A list of values
An array holds an ordered list. [90, 75, 82] makes one, and the type is written [Int]. Positions start at zero, so the first value is at index zero, and .count gives how many there are.
A var array can grow with .append(...) and be reordered with .sorted(). Store it with let when the list itself should not change.
first and last return optionals, because an empty array has neither. Subscripting with [0] does not: it returns a plain element and stops the program when the index is out of range. That difference is deliberate — a position you chose is assumed to exist, while the first item may genuinely be absent.
Working on the whole list
Four tools save you from writing loops. .map changes every value into a new value, .filter keeps the ones that pass a test, .sorted puts them in order, and .reduce folds the whole list into a single answer.
Each takes a small block of code that says what to do with one item. A short block can use $0 for the item and $1 for the second one, which keeps the line tight.
The methods chain because each returns a new array. scores.filter { $0 >= 75 }.map { $0 / 10 } keeps the passing scores, then divides each one, and the second block only ever sees values that passed. Reading the chain left to right is reading the order the work happens in.
Dictionaries: keys and values
A dictionary looks up a value by a key instead of a position. ["Ada": 36] maps the key "Ada" to the value 36, and the type is written [String: Int].
Looking up a key gives an optional, because the key may not be there. That is the optional from the last chapter doing its usual job: the answer may be missing, and you handle it.
Assigning nil to a key removes it: ages["Alan"] = nil deletes the entry rather than storing a missing value. The default: subscript is the other useful form, counts[word, default: 0] += 1, which reads the old count or zero, adds one, and writes it back without an optional in sight.
Arrays are values, dictionaries are unordered
An array is a value. var copy = scores makes a second array, and changing one does not change the other. Swift shares the storage until a write happens, so the copy is cheap, but the behaviour you see is a true copy.
A dictionary is not ordered. Its keys come back in whatever order the table finds convenient, so sort them before printing. keys.sorted() gives a steady order and makes two runs comparable.
Because arrays are values, assigning one to another copies it; changing the copy does not change the original, which is the opposite of a reference type.
A dictionary key must be Hashable, which means it can be reduced to an integer the table can use as a starting point. String, Int and most simple values qualify. The hash is not the value’s identity; two equal keys must hash the same, and the table then compares them properly to settle a collision.
A worked chain
Take [90, 75, 82, 60]. filter { $0 >= 75 } keeps 90, 75 and 82. map { $0 / 10 } turns them into 9, 7 and 8, using whole-number division. reduce(0, +) adds 24. The original array is untouched at every step, so it can be used again for a different report.
The same result can be written as a loop with a running total, and for a very long array that is often faster. The chain is shorter and says what happens rather than how: keep, transform, fold. Choose the form that makes the intent obvious, and reach for the loop when the intermediate arrays become the cost that matters.
Four tools and one lookup
var numbers = [3, 1, 4, 1, 5]
numbers.append(9)
print(numbers.sorted())
let doubled = numbers.map { $0 * 2 }
let big = numbers.filter { $0 > 3 }
let total = numbers.reduce(0, +)
var ages = ["Ada": 36]
ages["Alan"] = 41
print(ages.keys.sorted())Three mistakes cause most collection bugs. An index must be less than count, because the last valid position is count - 1. A dictionary lookup returns an optional even for a key that looks familiar, so open it or give it a fallback. And sorted() returns a new array while sort() changes the one you call it on; choosing the wrong one either loses the order or fails on a let.
A list of scores, a table of ages
Run it and check the totals. Then add one more score to the list and predict how the count, the passing list and the total change.
Try these next
- Add three numbers to an array, then print the first, the last and the count.
- Build a dictionary in a loop, then print its keys sorted by name.
- Take a list of scores, keep the passing ones, double them, and sum the result in one chain.
Count the words in a list
Run it and check each frequency. Then add another repeated word and predict which counts change and which stay the same.
Sorting a dictionary by its keys before printing gives a steady, predictable order. That habit keeps output the same every run and makes reports easy to read.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
What does map give when its block doubles each value?
