Last active
April 27, 2018 14:02
-
-
Save erica/69f2fd1079482e17d924c0f42fb78e5e to your computer and use it in GitHub Desktop.
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 strided non-contiguous sequence of elements that incorporates | |
/// every nth element of a base sequence. | |
/// | |
/// When used with collections, the sequence includes the first element | |
/// followed by the element at the `startIndex` offset by the `stride`, | |
/// by 2 * the `stride`, etc. | |
/// | |
/// ``` | |
/// for value in myArray.striding(by: 5) { | |
/// // process every 5th member, starting with the | |
/// // first member of `myArray`: | |
/// // | |
/// // myArray[0], myArray[0 + strideLength], | |
/// // myArray[0 + 2 * strideLength], ... | |
/// } | |
/// ``` | |
/// | |
/// To stride across a subsequence, use a collection slice: | |
/// ``` | |
/// let results = Array(myArray[5...20].striding(by: 2)) | |
/// ``` | |
/// | |
public struct StridedSequence<BaseSequence: Sequence> : Sequence, IteratorProtocol { | |
public typealias Stride = Int | |
public mutating func next() -> BaseSequence.Element? { | |
defer { | |
for _ in 0 ..< _strideLength - 1 { | |
let _ = _iterator.next() | |
} | |
} | |
return _iterator.next() } | |
/// Access only through `Sequence.striding(by:)` | |
internal init(_ sequence: BaseSequence, stride strideLength: StridedSequence.Stride) { | |
_iterator = sequence.makeIterator() | |
_strideLength = strideLength | |
} | |
internal var _iterator: BaseSequence.Iterator | |
internal var _strideLength: StridedSequence.Stride | |
} | |
extension Sequence { | |
/// Returns a strided iterator of sequence elements. The | |
/// stride length is set to incorporate every nth element. | |
/// | |
/// - Parameter strideLength: the distance for each stride | |
/// - Returns: A strided sequence of values | |
public func striding(by strideLength: StridedSequence<Self>.Stride) -> StridedSequence<Self> { | |
guard strideLength > 0 else { fatalError("Stride must be positive")} | |
return StridedSequence(self, stride: strideLength) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment