Created
September 2, 2020 23:41
-
-
Save IanKeen/70e076e7bdc4ef73fa7e9631026a0c39 to your computer and use it in GitHub Desktop.
Iterate a sequence with access to the previous/next elements if they exist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// A collection that returns the current element as well as the previous and next elements when available | |
public struct NeighborSequence<Base: Sequence>: Sequence { | |
public typealias Element = (previous: Base.Element?, current: Base.Element, next: Base.Element?) | |
private let base: Base | |
fileprivate init(_ base: Base) { | |
self.base = base | |
} | |
public func makeIterator() -> AnyIterator<Element> { | |
var iterator = base.makeIterator() | |
var previous: Base.Element? | |
var currentValue = iterator.next() | |
return .init { | |
guard let current = currentValue else { return nil } | |
defer { previous = current } | |
let next = iterator.next() | |
currentValue = next | |
return (previous, current, next) | |
} | |
} | |
} | |
extension Sequence { | |
/// Return `Self` as a `NeighborSequence` | |
/// | |
/// Each element in a `NeighborSequence` returns the element at the specified | |
/// index as well as the previous and next elements when possible. | |
/// | |
/// This allows you to see either side of a given element. | |
public var neighbors: NeighborSequence<Self> { | |
return .init(self) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment