Removing elements from an array
Swift arrays have no method named pop. The same job is done by removeLast(), which takes the final element out of the array. Like append, it changes the array in place, so the array has to be declared with var.
var fruits = ["mango", "kiwi", "grapefruit"]
fruits.removeLast()
print(fruits)
["mango", "kiwi"]
The removed element comes back
removeLast() returns the element it removed, so you can keep it in a constant. You can also ignore the result, as the lesson does, without any warning.
var fruits = ["mango", "kiwi", "grapefruit"]
let last = fruits.removeLast()
print(last)
print(fruits)
grapefruit
["mango", "kiwi"]
Removing from other positions
Two sibling methods work on different positions:
removeFirst()removes and returns the first element.remove(at:)removes and returns the element at a given index. The elements after it move one place to the left.
var threeArr = [1, 4, 6]
threeArr.remove(at: 1)
print(threeArr)
threeArr.remove(at: 0)
print(threeArr)
[1, 6]
[6]
Copies are unaffected
Arrays are value types, so removing from one variable does not change a copy made earlier:
var x = [1, 2, 3]
let y = x
x.removeLast()
print(x, y)
[1, 2] [1, 2, 3]
The array y is a let constant, and that is fine here: nothing in the code changes y.
Empty arrays
removeLast(), removeFirst() and remove(at:) all assume the element exists. Calling them on an empty array, or with an index past the end, stops the program with a run-time error. When the array might be empty, use popLast() instead. It returns an optional: the last element, or nil when there is nothing to remove.
var ages = [14, 32]
print(ages.popLast() as Any)
print(ages.popLast() as Any)
print(ages.popLast() as Any)
print(ages)
Optional(32)
Optional(14)
nil
[]
Unlike the remove methods, popLast() produces a result that the compiler expects you to use, so calling it without storing or printing the result gives a warning. Reading ages.isEmpty first is another safe way to guard a removal.
Using append and popLast as a stack
Appending to the end and removing from the end together make a stack: the last element added is the first one taken out. A while let loop with popLast() drains it, and stops by itself when the array is empty:
var stack: [String] = []
stack.append("a")
stack.append("b")
stack.append("c")
while let top = stack.popLast() {
print(top)
}
print(stack)
c
b
a
[]
To empty an array in one step, call removeAll(). To remove every element that meets a condition, give removeAll(where:) a closure. With ages set to [14, 32, 50, 21], the call ages.removeAll(where: { $0 > 30 }) leaves [14, 21]. The closure runs once per element, and $0 is the element being tested.
The exercise
The starter code has two arrays, both declared with var:
- Call
removeLastonfruitsonce."grapefruit", the last fruit, disappears. - Call
removeLastonagestwice. Each call removes whatever is last at that moment, so the first call removes21and the second removes50.
var fruits = ["mango", "kiwi", "grapefruit"]
var ages = [14, 32, 50, 21]
fruits.removeLast()
ages.removeLast()
ages.removeLast()
Afterwards fruits is ["mango", "kiwi"] and ages is [14, 32].
Common mistakes
- Using
let. Removing from aletarray is a compile error, just as appending is. - Removing from an empty array. The program crashes at run time. Check
isEmptyor usepopLast(). - Counting calls wrongly. Two calls remove two elements, not the same one twice.
- Using a wrong index. Indexes start at 0, and the last valid index is
count - 1.
Key takeaways
removeLast()is Swift's pop. It removes the last element and returns it.removeFirst()andremove(at:)remove from the front or from any index.popLast()is the safe version that returnsnilfor an empty array.
