Mutating an Array while iterating over it

by @ralfebert · updated November 04, 2021
Xcode 13 & iOS 15
Swift Examples

What is the best way to change a list while iterating it in Swift?

The most straightforward way is to use the indices:

struct Position {
    var amount = 0
}

struct Booking {
    var positions: [Position]

    mutating func increment() {
        for idx in positions.indices {
    positions[idx].amount += 1
}
    }
}

var booking = Booking(positions: [Position](repeating: Position(), count: 3))
booking.increment()
print(booking)

You could optimize it a tiny bit by using the index methods to avoid an unnecessary copy (although I'd only use this for large arrays / if it turns out to be a performance issue):

mutating func increment() {
    var idx = positions.startIndex
    while idx != positions.endIndex {
        positions[idx].amount += 1
        idx = positions.index(after: idx)
    }
}

More information

↗ Collection#indices
↗ How to mutate a struct object when iterating over it