Some stride-related discussions took place on the forums today. I was inspired to play with strides as I took a break between my kids’ appointments. If any of this resonates with you as a potential user for it, let me know.

### Index Strides

The following extension allows you to stride over a collection’s indices.

```extension BidirectionalCollection where Index: Strideable {
/// Returns the sequence of collection elements (`self[start]`,
/// `self[start + stride]`, `self[start + 2 * stride]` ... *last*
/// where *last* is the last element in the collection whose index
/// is less than or equal to `end`.
///
/// - Note: There is no guarantee that the element at index `end`
///   is part of the sequence
///
/// - Parameter start: The starting index
/// - Parameter end: The upper index bound
/// - Parameter distance: The stride for each successive index
/// - Returns: A lazy sequence of collection members
public func stride(from start: Index, through end: Index, by distance: Index.Stride) -> LazyMapSequence<StrideThrough<Index>, Element> {
return Swift.stride(from: start, through: end, by: distance)
.lazy.map({ self[\$0] })
}

/// Returns the sequence of collection elements (`self[start]`,
/// `self[start + stride]`, `self[start + 2 * stride]` ... *last*
/// where *last* is the last element in the collection whose index
/// is strictly less than `end`.
///
/// - Parameter start: The starting index
/// - Parameter end: The upper index bound
/// - Parameter distance: The stride for each successive index
/// - Returns: A lazy sequence of collection members
public func stride(from start: Index, to end: Index, by distance: Index.Stride) -> LazyMapSequence<StrideTo<Index>, Element> {
return Swift.stride(from: start, to: end, by: distance)
.lazy.map({ self[\$0] })
}
}
```

Here’s an example that uses this approach to form a sequence that strides through the collection:

```let myArray = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
for value in myArray.stride(from: 0, through: myArray.count, by: 3) {
print(value) // a, d, g, j
}```

### Range Operators

The next snippet uses the division operator to create its stride. This was pitched by “Tony Y” in a forum thread.

```extension CountableClosedRange {
static func / (range: CountableClosedRange, divisor: Bound.Stride) -> StrideThrough<Bound> {
let distance = range.distance(from: range.startIndex, to: range.endIndex) / divisor // deprecated
return Swift.stride(from: range.lowerBound, through: range.upperBound, by: distance)
}
}```

In this example, you just “divide” the range:

```for idx in (0 ... 100) / 5 {
print(idx) // 0, 20, 40, 60, 80, 100
// yes that's 6 not 5, but isn't that what
// you want? 5 subranges between each index?
}
```

Because I wrote this fairly quickly, I used the deprecated `range.distance` function as straight index arithmetic seemed to error:

```error: binary operator '-' cannot be applied to two 'ClosedRangeIndex' operands
let distance = (range.endIndex - range.startIndex) / divisor```

As usual, I probably messed up somewhere (or several somewheres) or you might see ways I could improve the code. Let me know!

Update: After some thought, I decided I preferred a sequence of subranges (which should probably be a type and not like I do it here):

```extension CountableClosedRange {
static func / (range: CountableClosedRange, divisor: Bound.Stride) -> UnfoldSequence<CountableClosedRange<Bound>, (CountableClosedRange<Bound>?, Bool)> {
let distance = range.distance(from: range.startIndex, to: range.endIndex) / divisor
let rangeStride = Swift.stride(from: range.lowerBound, through: range.upperBound, by: distance)
var indices = Array(rangeStride)
indices.append(range.upperBound)
indices.reverse()
guard var current = indices.popLast(), var next = indices.popLast() else {
fatalError("Guaranteed count failed in index population")
}
var done = false
return sequence(first: current ... next.advanced(by: -1), next: { _ in
guard !done else { return nil }
(current, next) = (next, indices.popLast()!)
if current == next {
done = true
return next ... next
} else if next == range.upperBound && indices.isEmpty  {
done = true
return current ... next
} else {
}
})
}
}

for idx in (0 ... 99) / 5 {
print(idx) // 0...19, 20...39, 40...59, 60...79, 80...99
}

for idx in (0 ... 100) / 5 {
print(idx) // 0...19, 20...39, 40...59, 60...79, 80...99, 100...100
}```

This isn’t a debugged solution. For example, trying to divide 1 … 1 by 1 or 1 … 2 by 1 will both fail.

• Lovely, as usual. Thank you, Erica!

Where you are striding through a collection (as in the first example), it is important to use the `to` method since the `through` will crash where the count of elements is a multiple of the `stride`:

“`swift
let myArray = [1, 2, 3]
for _ in myArray.stride(from: 0, through: 3, by: 3) {} // Fatal error: Index out of range
“`

When I implemented `stride` method on `RandomAccessCollection` for our team, I took this into account and arrived at this api:

“`swift
let ints = 1…100
ints.prefix(9).stride(by: 3) // → [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
ints.prefix(9).stride(by: 3, spanning: 2) // → [[1, 2], [4, 5], [7, 8]]
“`

In my case, this method returns a lazy `StridingSubsequence<Slice<CountableClosedRange>>`.

• Forgot to mention, I also have:

``` ints.prefix(4).strideAround(by: 1, spanning: 3) // [[1, 2, 3], [2, 3, 4], [3, 4, 1], [4, 1, 2]] ```

``` ```

`... although this would be more useful as an infinite sequence...`

• Soroush and I worked on this for a bit and here’s what we came up with: Adding Strideable Sequences