Skip to content
Theory · Arrays · lesson 2 of 8

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:

SWIFT
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:

  1. append(4) adds 4 at the end, and the array becomes [7, 9, 4].
  2. insert(10, at: 0) inserts 10 at index 0, and the other elements move to the right.
  3. remove(at: 1) takes away the element at index 1—that is 7—and returns it, so 7 ends up in the constant removed.
  4. scores[0] = 8 puts 8 in place of 10.

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:

SWIFT
let more = scores + [5, 6]
print(scores.count, more.count)  // 3 5

scores 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:

SWIFT
let days = [1, 2, 3]
days.append(4) // ✗
TEXT
error: cannot use mutating member on immutable value: 'days' is a 'let' constant

The 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

  • append adds at the end, insert(_:at:) inserts at an index, and remove(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 let cannot change: you cannot add, remove or replace an element.