What these two methods do
append only adds at the end. When an item has to go somewhere else, Swift gives you insert(_:at:). You write the value first and the index after at:. The items from that index on shift one place to the right to make room.
var colors = ["red", "green", "blue"]
colors.insert("pink", at: 1)
print(colors)
["red", "pink", "green", "blue"]
remove(at:) does the opposite. It takes out the item at an index, and the items after it shift one place to the left to close the gap.
colors.remove(at: 0)
print(colors)
["pink", "green", "blue"]
Details worth knowing
remove(at:) hands the item back
The removed item is the method's result, so you can keep it:
var pets = ["Rex", "Milo", "Luna"]
let gone = pets.remove(at: 1)
print(gone)
print(pets)
Milo
["Rex", "Luna"]
If you don't need it, just ignore it: Swift doesn't complain.
Valid indexes
For insert, the index can be anything from 0 up to count. Inserting at count puts the item at the end. For remove(at:), the index must be an existing one, from 0 to count - 1. An index outside those limits stops the program with a run-time error.
Here is insert at the very end next to insert at the front, using the line after Milo has gone home:
pets.insert("Zed", at: pets.count)
print(pets)
pets.insert("Ada", at: 0)
print(pets)
["Rex", "Bella", "Luna", "Zed"]
["Ada", "Rex", "Bella", "Luna", "Zed"]
Inserting at index 0 shifts every item. That is fine for a short list like this one, but it is the reason a long array is slower to change at the front than at the end: all the items behind the spot have to move.
The array must be a var
Both methods change the array, so it has to be declared with var. With let, the compiler refuses:
error: cannot use mutating member on immutable value: 'pets' is a 'let' constant
Indexes move
After an insert or a removal, every item behind that spot has a new index. If you plan a second change, work out the indexes after the first one.
The exercise: a vet's waiting line
pets starts as ["Rex", "Milo", "Luna"]. Bella has an appointment, so she goes second, at index 1:
pets.insert("Bella", at: 1)
The line is now ["Rex", "Bella", "Milo", "Luna"], so pets.count prints 4. Milo, who used to be at index 1, moved to index 2. That is why the next step removes index 2 and not 1:
pets.remove(at: 2)
The line is now Rex, Bella and Luna. The finished program:
var pets = ["Rex", "Milo", "Luna"]
pets.insert("Bella", at: 1)
print(pets.count)
pets.remove(at: 2)
print(pets[0], pets[1], pets[2])
It prints:
4
Rex Bella Luna
Both calls look at the array as it is at that moment, line by line. That is why the order of the two lines matters: swap them, and index 2 would still hold Luna, because Bella wouldn't be in the line yet.
Common mistakes
- Writing the index first. It is
insert("Bella", at: 1), with the value before the index. - Removing by the old index. Once Bella is in, Milo is at 2, not 1. Removing index 1 would send Bella home instead.
- Declaring the array with
let.
Key takeaways
insert(x, at: i)putsxat indexiand shifts the rest right.remove(at: i)takes out the item ati, returns it, and shifts the rest left.- Both need a
vararray and an index in range.
