Subscript assignment
The entries of a Swift array are mutable: you can replace any of them using its index. Write the array's name, the index in square brackets, then = and the new value.
var numbers = [50, 40, 30]
numbers[0] = 15
numbers[2] = -1
print(numbers) // [15, 40, -1]
Two things are involved: the index says which slot to change, and the value says what to store there. The slot at index 1 is untouched, and the length of the array stays 3.
Requirements
- The array is declared with
var. Aletarray can't be changed, sofruits[0] = "apple"on a constant fails to compile with a message that the array is aletconstant. - The index exists. The subscript replaces an existing element. Assigning to an index equal to or beyond
countcrashes the program, and it does not grow the array. To add elements, useappend. - The value has the element type. You can store an
Intin an[Int], but not aStringor aDouble.
Updating with the current value
To change an element relative to its old value, use a compound operator. It reads the current value, applies the operation and stores the result in the same slot:
var ages = [14, 32, 50, 21]
ages[1] += 5
print(ages) // [14, 37, 50, 21]
The line is shorthand for ages[1] = ages[1] + 5. -=, *= and the other compound operators work the same way. Strings have += too, which appends text: fruits[0] += "s" would turn "mango" into "mangos".
Changing every element
A loop over the valid indexes can update each element in place:
var scores = [14, 37, 50, 21]
for i in 0..<scores.count {
scores[i] += 1
}
print(scores) // [15, 38, 51, 22]
Looping with for score in scores and writing score += 1 does not compile. The loop variable is a constant copy of each element, so it can't be used to change the array.
Swapping two elements
Subscript assignment is also how you exchange two values. Keep one of them in a temporary constant first, or the first assignment would destroy it:
var a = [3, 1, 2]
let tmp = a[0]
a[0] = a[2]
a[2] = tmp
print(a) // [2, 1, 3]
Arrays also have swapAt(_:_:), which does the same in one call: a.swapAt(0, 1) turns [2, 1, 3] into [1, 2, 3].
Changes don't leak into copies
An array is a value type. After let backup = ages, the two names hold separate arrays, and a later ages[0] = 0 doesn't alter backup.
The exercise, step by step
- Change the first fruit. The first item sits at index 0, so assign
"apple"to it:fruits[0] = "apple". The string needs double quotes. - Add 5 to the second age. Index 1 holds 32. Use
ages[1] += 5, and the element becomes 37.
var fruits = ["mango", "kiwi", "grapefruit"]
var ages = [14, 32, 50, 21]
fruits[0] = "apple"
ages[1] += 5
Printing the arrays afterwards gives ["apple", "kiwi", "grapefruit"] and [14, 37, 50, 21].
Common mistakes
- Changing a
letarray. Switch the declaration tovar. - Off-by-one indexes. The first item is index 0 and the second is index 1.
fruits[1] = "apple"replaces"kiwi". - Replacing instead of adding.
ages[1] = 5overwrites 32 with 5, whileages[1] += 5gives 37. - Using a quoted index. The index is a number:
fruits[0], notfruits["0"].
Key takeaways
array[index] = valuereplaces one element and needs avararray.array[index] += nchanges an element based on its current value.- The index must exist and the value must match the element type.
- Use
appendto make an array longer; a subscript can't.
