大型/巨大的数组在部分处理时常常会出现问题,比如在这种情况下,创建两个额外的数组(即使是半大小)可能既浪费时间又浪费内存。例如,如果您只想计算奇数和偶数位置上数字的平均值和标准差,但这将需要调用一个需要序列作为输入的专用函数,该怎么办呢?
因此,为什么不创建两个子集合,它们不会复制数组内容,而是以透明的方式指向原始数组,以允许查询它们的元素:
extension Collection where Index: Strideable{
func stride(from: Index, to: Index, by: Index.Stride) -> StridedToCollection<Self> {
return StridedToCollection(self, from: from, to: to, by: by)
}
}
struct StridedToCollection<C>: Collection where C: Collection, C.Index: Strideable {
private let _subscript : (C.Index) -> C.Element
private let step: C.Index.Stride
fileprivate init(_ collection: C, from: C.Index, to: C.Index, by: C.Index.Stride) {
startIndex = from
endIndex = Swift.max(to, startIndex)
step = by
_subscript = { collection[$0] }
}
let startIndex: C.Index
let endIndex: C.Index
func index(after i: C.Index) -> C.Index {
let next = i.advanced(by: step)
return next >= endIndex ? endIndex : next
}
subscript(_ index: C.Index) -> C.Element {
return _subscript(index)
}
}
Collection
扩展和相关结构将创建一个伪数组,您可以使用它来访问您感兴趣的元素。
使用方法很简单:
let numbers: [Int] = [1, 2, 3, 4]
let stride1 = numbers.stride(from: 0, to: numbers.count, by: 2)
let stride2 = numbers.stride(from: 1, to: numbers.count, by: 2)
print(Array(stride1), Array(stride2))
通过上述方法,您可以迭代两个步长而不必担心会使内存量加倍。如果您确实需要两个子数组,只需使用
Array(stride)
即可。
O(n)
。只需创建两个新数组并循环遍历旧数组,在每次迭代中交替放置元素即可。 - royhowie