Well, you wouldn’t do it the same way. Every array has a first
and last
element that is either nil
or is an actual element. So every array has those properties that return 'Element?`
But not every array has a third, for instance, element. Some might only have 1 or 2. But using code like this:
let link = model.images.maps[3].link
will crash if there aren’t at least four items in the array. And since the default subscript for Array
returns a real value rather than an Optional
, you don’t even have the option to catch it with optional chaining or nil coalescing or a guard let
or anything like that.
You need to either a) check your array bounds first and make sure you aren’t requesting an index outside those bounds, or b) write an extension on Array
that creates a custom subscript to do that for you; something like this perhaps:
extension Array {
public subscript(safe index: Int) -> Element? {
guard (0..<endIndex).contains(index) else { return nil }
return self[index]
}
}
Sample usage:
struct MapElement {
let name: String
let link: String
}
let maps: [MapElement] = [
MapElement(name: "First Map", link: UUID().uuidString),
MapElement(name: "Second Map", link: UUID().uuidString),
MapElement(name: "Third Map", link: UUID().uuidString),
MapElement(name: "Fourth Map", link: UUID().uuidString),
]
let link = maps.first?.link //returns a value
let link3 = maps[safe: 3]?.link //returns a value
let link8 = maps[safe: 8]?.link //returns nil