When creating an array, we need to specify the type of the elements that we will be storing in the array; this is declared in angular brackets as part of the array's type declaration:
var moviesToWatch: Array<String> = Array()
moviesToWatch.append("The Shawshank Redemption")
moviesToWatch.append("Ghostbusters")
moviesToWatch.append("Terminator 2")
This uses a language feature called generics, which we will cover in detail in Chapter 4, Generics, Operators, and Nested Types.
The append method on the array will add a new element to the end of the array. Now that we have put some elements in the array, let's access those elements:
print(moviesToWatch[0]) // "The Shawshank Redemption"
print(moviesToWatch[1]) // "Ghostbusters"
print(moviesToWatch[2]) // "Terminator 2"
Elements in an array are numbered with a zero-based index, so the first element in the array is at index 0, the second at index 1, the third at index 2, and so on. We can access the elements in the array using a subscript, in which we provide the index of the element we want to access; a subscript is specified in square brackets after the array instance's name.
There is nothing to stop us from entering an index in the subscript that doesn't exist in the array, and this will cause a crash. Instead, we can use some index helper methods on Array to ensure that we have an index that is valid for this array. Enter the following at the end of the playground:
let index5 = moviesToWatch.index(moviesToWatch.startIndex,
offsetBy: 5,
limitedBy: moviesToWatch.endIndex)
print(index5 as Any) // Optional 5
let index10 = moviesToWatch.index(moviesToWatch.startIndex,
offsetBy: 10,
limitedBy: moviesToWatch.endIndex)
print(index10 as Any) // nil
The index method lets us specify an offset, but binds it to the start and end index of the array. This will return the valid index if it is within the bound, or nil if it is not, since by the end of the playground, the moviesToWatch array has 6 elements, in which case retrieving index 5 is successful, but index 10 returns nil.
In the next chapter, we will cover how to make decisions based on whether this index exists, but for now, it's just useful to know that this method is available:
print(moviesToWatch.count) // 3
Arrays have a count property that will tell us how many elements they store, so when we add an element, this value will change:
moviesToWatch.insert("The Matrix", at: 2)
Elements can be inserted at any place in the array using the same zero-based index that we used in the preceding code. So, by inserting "The Matrix" at index 2, it will be placed at the third position in our array, and all elements at position 2 or greater will be moved down by 1.
This increases the array's count:
print(moviesToWatch.count) // 4
The array also provides some helpful computed properties for accessing elements at either end of the array:
let firstMovieToWatch = moviesToWatch.first
print(firstMovieToWatch as Any) // Optional("The Shawshank Redemption")
let lastMovieToWatch = moviesToWatch.last
print(firstMovieToWatch as Any) // Optional("Terminator 2")
let secondMovieToWatch = moviesToWatch[1]
print(secondMovieToWatch) // "Ghostbusters"
These properties are optional values as the array may be empty, and if it is, these will be nil. Conversely, accessing an element via the index subscript returns a non-optional value, as the assumption is made that if you have a valid index, you will get a valid value.
Along with retrieving values via the subscript, we can assign values to an array subscript:
moviesToWatch[1] = "Ghostbusters (1984)"
This will replace the element at the given index with the new value.
In the preceding code, we created an empty array and then appended values to it. But, we can also create an array that already contains values using an array literal:
let spyMovieSuggestions: [String] = ["The Bourne Identity", "Casino Royale", "Mission Impossible"]
An array type can be specified with the element type enclosed by square brackets, and the array literal can be defined by comma-separated elements within square brackets. So, we can define an array of integers like this:
let fibonacci: [Int] = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
As we have seen earlier, the compiler can often infer the type from the value we assign, and when the type is inferred, we don't need to specify it. In both the preceding arrays, spyMovieSuggestions and fibonacci, all the elements in the array are of the same type, String and Int respectively; so the array's type can be inferred, and therefore omitted, as follows:
let spyMovieSuggestions = ["The Bourne Identity", "Casino Royale", "Mission Impossible"]
let fibonacci = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
Arrays can be combined using the + operator:
moviesToWatch = moviesToWatch + spyMovieSuggestions
This will create a new array by appending the elements in the second array to the first:
var starWarsTrilogy = Array<String>(repeating: "Star Wars: ", count: 3)
The array provides a convenience initializer that will fill an array with elements. Let's access, append, and assign all of them in a single line:
starWarsTrilogy[0] = starWarsTrilogy[0] + "A New Hope"
starWarsTrilogy[1] = starWarsTrilogy[1] + "Empire Strikes Back"
starWarsTrilogy[2] = starWarsTrilogy[2] + "Return of the Jedi"
The array also provides a helper for replacing a range of values with the values contained in another array:
moviesToWatch.replaceSubrange(2...4, with: starWarsTrilogy)
Here, we have specified a range using ... to indicate a range between two integer values, inclusive of those values. So this range contains the integers 2, 3, and 4.
This way to specify a range will be used in the subsequent chapters. Alternatively, you can specify a range that goes up to, but not including, the top of the range, known as a half-open range:
moviesToWatch.replaceSubrange(2..<5, with: starWarsTrilogy)
We've added elements, accessed them, and replaced them; let's see how to delete elements from an array:
moviesToWatch.remove(at: 6)
Provide the index of the element to the remove method, and the element at that index will be removed from the array, with all the subsequent elements moving up one place to fill the empty space. This will reduce the array's count by 1.