|
3 | 3 | [[Source](https://github.com/apple/swift-algorithms/blob/main/Sources/Algorithms/Stride.swift) | |
4 | 4 | [Tests](https://github.com/apple/swift-algorithms/blob/main/Tests/SwiftAlgorithmsTests/StrideTests.swift)] |
5 | 5 |
|
6 | | -A type that steps over sequence elements by the specified amount. |
| 6 | +Step over the elements of a sequence elements by a specified amount. |
7 | 7 |
|
8 | 8 | This is available through the `striding(by:)` method on any `Sequence`. |
9 | 9 |
|
10 | 10 | ```swift |
11 | 11 | (0...10).striding(by: 2) // == [0, 2, 4, 6, 8, 10] |
12 | 12 | ``` |
13 | 13 |
|
14 | | -If the stride is larger than the count, the resulting wrapper only contains the |
15 | | -first element. |
| 14 | +If the stride is larger than the length of the sequence, the resulting wrapper |
| 15 | +only contains the first element. |
16 | 16 |
|
17 | 17 | The stride amount must be a positive value. |
18 | 18 |
|
19 | 19 | ## Detailed Design |
20 | 20 |
|
21 | | -The `striding(by:)` method is declared as a `Sequence` extension, and returns a |
22 | | -`StridingSequence` type: |
| 21 | +The `striding(by:)` method is declared in extension of both `Sequence` and |
| 22 | +`Collection`: |
23 | 23 |
|
24 | 24 | ```swift |
25 | 25 | extension Sequence { |
26 | | - public func striding(by step: Int) -> StridingSequence<Self> |
| 26 | + public func striding(by step: Int) -> StridingSequence<Self> |
27 | 27 | } |
28 | | -``` |
29 | | - |
30 | | -A custom `Index` type is defined so that it's not possible to get confused when |
31 | | -trying to access an index of the stride collection. |
32 | 28 |
|
33 | | -```swift |
34 | | -[0, 1, 2, 3, 4].striding(by: 2)[1] // == 1 |
35 | | -[0, 1, 2, 3, 4].striding(by: 2).map { $0 }[1] // == 2 |
| 29 | +extension Collection { |
| 30 | + public func striding(by step: Int) -> StridingCollection<Self> |
| 31 | +} |
36 | 32 | ``` |
37 | 33 |
|
| 34 | +The reason for this distinction is subtle. The `StridingSequence.Iterator` type |
| 35 | +is unable to skip over multiple elements of the wrapped iterator at once since |
| 36 | +that's not part of `IteratorProtocol`'s interface. In order to efficiently |
| 37 | +stride over collections that provide a fast way of skipping multiple elements at |
| 38 | +once, the `StridingCollection` type was added which does not provide a custom |
| 39 | +`Iterator` type and therefore always strides over the underlying collection in |
| 40 | +the fastest way possible. See the related |
| 41 | +[GitHub issue](https://github.com/apple/swift-algorithms/issues/63) for more |
| 42 | +information. |
| 43 | + |
38 | 44 | A careful thought was given to the composition of these strides by giving a |
39 | 45 | custom implementation to `index(_:offsetBy:limitedBy)` which multiplies the |
40 | 46 | offset by the stride amount. |
|
0 commit comments