Changing an array
In the previous lesson the row of lockers was ready in advance. But a row can also be rebuilt: you can add a locker at the end, put a new one in the middle or take one away.
An array declared with var can do the same. This program changes a row of marks four times and prints it after each change:
var scores = [7, 9]
scores.append(4)
print(scores) // [7, 9, 4]
scores.insert(10, at: 0)
print(scores) // [10, 7, 9, 4]
let removed = scores.remove(at: 1)
print(removed, scores) // 7 [10, 9, 4]
scores[0] = 8
print(scores) // [8, 9, 4]Let's go through what each change does:
append(4)adds4at the end, and the array becomes[7, 9, 4].insert(10, at: 0)inserts10at index0, and the other elements move to the right.remove(at: 1)takes away the element at index1—that is7—and returns it, so7ends up in the constantremoved.scores[0] = 8puts8in place of10.
append, insert and remove are methods of the array: you call them with a dot after the array's name, like the methods of strings.
Four ways to change an array
append—at the end
scores.append(4) adds an element after the last one. count grows by one, and the indices of the old elements stay the same.
insert(_:at:)—at an index
scores.insert(10, at: 0) puts the element in the place with index 0. All elements from that place on move one position to the right: 7 was at index 0, and now it is at index 1. The index for inserting goes from 0 to count, and inserting at index count works like append.
remove(at:)—take away
scores.remove(at: 1) takes the element away, and the elements to its right move left so that no gap is left in the row. The method returns the removed value: you can keep it, like removed in the example, or leave it unused.
Assigning at an index
scores[0] = 8 replaces an element, and the number of elements stays the same. This way you change only an element that already exists. An index past the bounds of the array crashes the program both here and in remove(at:).
Here the locker picture is inaccurate. A locker's number is written on its door once and for all, but in an array the indices are renumbered after insert and remove. They always go in a row, from 0 to count - 1.
Joining with +
The + operator joins two arrays of one type into a new array. It does not change the original arrays:
let more = scores + [5, 6]
print(scores.count, more.count) // 3 5scores still has three elements, and the new array more has five. That is why + works with arrays declared with let too.
Common mistake
An element added to an array declared with let:
let days = [1, 2, 3]
days.append(4) // ✗error: cannot use mutating member on immutable value: 'days' is a 'let' constantThe program does not compile. An array declared with let is a constant as a whole: you cannot add, insert, remove or replace a single element in it. Replacing at an index gives a similar error: cannot assign through subscript: 'days' is a 'let' constant. If the row must change, declare it with var.
Interviewers often ask whether you can change an array declared with let. In JavaScript, for example, a constant only forbids binding the name to another array, while the array itself can still change. In Swift, let freezes the contents too.
Key points
appendadds at the end,insert(_:at:)inserts at an index, andremove(at:)removes an element and returns it.- After inserting and removing, the indices are renumbered and again go in a row from zero.
+creates a new array and leaves the originals unchanged.- An array declared with
letcannot change: you cannot add, remove or replace an element.