我正在尝试分割数组的安全方法.
我知道你可以把一个数组的子集做成这样的事情:
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)
编辑:更新为更直接的版本。
只是为了练习。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)
...或替代 - 更直接 - 版本;
您可以执行以下操作:
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的数组).