For In Loops in Viewbuilder?

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
1 Like