Getting the length
Every Swift array has a count property that holds the number of elements in it. Swift's name for the length is count: there is no length property on an array.
let ourArray = [50, 40, 30]
print(ourArray.count) // 3
Two details are easy to miss. count is a property, not a method, so it takes no parentheses: ourArray.count() doesn't compile. And its type is Int, the same type used for indexes, so you can use it directly in index arithmetic without conversions. An empty array has a count of 0, and isEmpty is the readable way to ask that question.
Count versus last index
The count is how many elements there are. The last index is one less, because indexing starts at 0:
| Array | count | Valid indexes | Last index |
|---|---|---|---|
[50, 40, 30] | 3 | 0, 1, 2 | 2 |
[14, 32, 50, 21] | 4 | 0, 1, 2, 3 | 3 |
This is why ourArray[ourArray.count] is always wrong: it points one position past the end.
Reaching items from the end
Subtracting from the count walks backwards from the end of the array:
let ourArray = [50, 40, 30]
print(ourArray[ourArray.count - 1]) // 30, the last item
print(ourArray[ourArray.count - 2]) // 40, the second to last item
The advantage over typing ourArray[2] is that the expression keeps working when the array's size changes. For an array that may be empty, check isEmpty first: with a count of 0, the index count - 1 is -1, which is invalid.
A note on "static"
For an array that never changes, the count never changes either, so you could compute it once. A var array that grows or shrinks reports its current size every time you ask.
Count in loops
The count sets the bounds of a loop. The range 0..<ages.count stops before the count, so it produces exactly the valid indexes 0, 1, 2 and 3 for a four-element array. Counting down from the end uses count - 1 as the starting index:
let ages = [14, 32, 50, 21]
var i = ages.count - 1
while i >= 0 {
print(ages[i], terminator: " ")
i -= 1
}
// prints: 21 50 32 14
Integer division gives a middle element: ages[ages.count / 2] is index 2 here, which holds 50. Division of integers drops the fraction, so for an odd count it lands on the true middle.
A safe way to read the last element of an array that might be empty is to test first: ages.isEmpty ? -1 : ages[ages.count - 1] gives 21 for ages and -1 for an empty array.
The exercise, step by step
The starter code declares fruits (three items) and ages (four items).
- Print the length of
fruits. Useprint(fruits.count). It prints3, the number of elements, not the last index. - Print the last age. The last index is
ages.count - 1, which is 3, soprint(ages[ages.count - 1])prints21. - Print the second to last age. Go one position further back with
ages.count - 2, which is index 2:print(ages[ages.count - 2])prints50.
let fruits = ["mango", "kiwi", "grapefruit"]
let ages = [14, 32, 50, 21]
print(fruits.count)
print(ages[ages.count - 1])
print(ages[ages.count - 2])
The output is 3, 21 and 50, one per line.
Common mistakes
- Writing
count(). It is a property. Leave the parentheses off. - Looking for
length. Other languages use that name, but Swift arrays havecount. - Using
countas an index.ages[ages.count]is out of range and crashes the program. - Subtracting too little or too much. The last item is
count - 1, the one before itcount - 2. - Indexing an empty array from the end. An empty array has no last item.
Key takeaways
array.countis the number of elements, as anInt.- The last index is
count - 1; the second to last iscount - 2. countis a property, so it has no parentheses.- Check
isEmptybefore reaching for an element from the end.
