如何在Swift中创建一个安全的数组子集?

sha*_*ked 1 arrays ios swift

我正在尝试分割数组的安全方法.

我知道你可以把一个数组的子集做成这样的事情:

let arr = [1,2,3,4,5]
print(arr[0..<3])
Run Code Online (Sandbox Code Playgroud)

它会打印出来 [1,2,3]

如果你尝试以下相同的 arr

print(arr[3..<9])
Run Code Online (Sandbox Code Playgroud)

该程序将崩溃

我想创建一个数组扩展而不是崩溃,产生尽可能多的元素,因此它将打印 [4,5]

subscript(safe range: Range) -> Element? {

}
Run Code Online (Sandbox Code Playgroud)

Joa*_*son 7

编辑:更新为更直接的版本。

只是为了练习。safe为清楚起见,与其他名称相同;请注意,它不返回 nil 而是返回一个空数组用于越界索引,这在许多情况下避免了使用代码中的空检查。

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]
Run Code Online (Sandbox Code Playgroud)

...或替代 - 更直接 - 版本;


ske*_*ech 6

您可以执行以下操作:

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]
Run Code Online (Sandbox Code Playgroud)

编辑:鉴于起始索引可能不是数组的开头的注释,我进行了修改,以便返回的切片始终从startIndex开始,即使endIndex超出了数组的边界(除非起始索引在endIndex之后)在这种情况下返回nil的数组).