Not a direct answer to the question but the elements of the sequence should be computed lazily. You should use Swift UnfoldSequence
type as follow:
extension Collection {
var unfoldedNeighbors: UnfoldSequence<SubSequence,Index> {
sequence(state: startIndex) { start in
guard start < endIndex else { return nil }
guard let end = index(start, offsetBy: 2, limitedBy: endIndex) else {
return nil
}
defer { formIndex(after: &start) }
return self[start..<end]
}
}
var neighborsSubsequences: [SubSequence] {
.init(unfoldedNeighbors)
}
var neighborsArrays: [[Element]] {
unfoldedNeighbors.map([Element].init)
}
}
Usage:
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for neighbors in numbers.unfoldedNeighbors {
print(neighbors)
}
If you need control the number of elements of each subsequence and also if it includes the tail or not:
extension Collection {
func unfoldedNeighbors(limitedTo length: Int, includesTail: Bool = false) -> UnfoldSequence<SubSequence,Index> {
sequence(state: startIndex) { start in
guard start < endIndex else { return nil }
guard let end = index(start, offsetBy: length, limitedBy: endIndex) else {
if includesTail {
defer { formIndex(&start, offsetBy: length-1, limitedBy: endIndex) }
return self[start...]
}
return nil
}
defer { formIndex(&start, offsetBy: length-1, limitedBy: endIndex) }
return self[start..<end]
}
}
func neighborsSequences(limitedTo length: Int, includesTail: Bool = false) -> [SubSequence] {
.init(unfoldedNeighbors(limitedTo: length, includesTail: includesTail))
}
func neighborsArrays(limitedTo length: Int, includesTail: Bool = false) -> [[Element]] {
unfoldedNeighbors(limitedTo: length, includesTail: includesTail).map([Element].init)
}
}
Usage:
let numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for neighbors in numbers.unfoldedNeighbors(limitedTo: 3, includesTail: true) {
print(neighbors)
}
This will print:
[1, 2, 3]
[3, 4, 5]
[5, 6, 7]
[7, 8, 9]
[9, 10]
let neighborsSequences = a.neighborsSequences(limitedTo: 3, includesTail: true) // [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]] of type [Array<Int>.SubSequence]
let neighborsArrays = a.neighborsArrays(limitedTo: 3, includesTail: true) // [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]] of type [[Int]]