Skip to content

Instantly share code, notes, and snippets.

@erica
Last active April 27, 2018 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erica/69f2fd1079482e17d924c0f42fb78e5e to your computer and use it in GitHub Desktop.
Save erica/69f2fd1079482e17d924c0f42fb78e5e to your computer and use it in GitHub Desktop.
/// 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