How to make a safe Array subset in Swift?

You could do the following:

extension Array {
    subscript(safe range: Range<Index>) -> ArraySlice<Element>? {
        if range.endIndex > endIndex {
            if range.startIndex >= endIndex {return nil}
            else {return self[range.startIndex..<endIndex]}
        }
        else {
            return self[range]
        }
    }
}

let a = [1,2,3]
a[safe: 1...3] // [2,3]

Edit: given the comment that the start index might not be the beginning of the array, I've amended so that the returned slice will always begin at startIndex even if the endIndex goes beyond bounds of the Array (unless start index is after endIndex of Array in which case nil is returned).


EDIT: Updated to a more straight forward version.

Just made for the practice. Same safe naming as the others used for clarity; note that it does not return nil but an empty array for out of bounds indexing, that avoids null checks in the consuming code for many cases.

extension Array {
    subscript(safe range: Range<Index>) -> ArraySlice<Element> {
        return self[min(range.startIndex, self.endIndex)..<min(range.endIndex, self.endIndex)]
    }
}

let a = [1,2,3]
a[safe: 1..<17] // [2,3]
a[safe: 4..<17] // []
a[safe: 1..<2]  // [2]

...or an alternate - more straight forward - version;

Tags:

Arrays

Ios

Swift