Skip to content

Commit 5289974

Browse files
author
Tim Vermeulen
committed
Various refactors
1 parent 88be07a commit 5289974

39 files changed

+658
-636
lines changed

Guides/Chunked.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ c.elementsEqual(c.chunked(...).joined())
6161

6262
## Detailed Design
6363

64-
The two methods are added as extension to `Collection`, with two matching
65-
versions that return a lazy wrapper added to `LazyCollectionProtocol`.
64+
The three methods are added as extension to `Collection`. `chunked(by:)` and
65+
`chunked(on:)` are eager by default, both with a matching version that return a
66+
lazy wrapper added to `LazySequenceProtocol`.
6667

6768
```swift
6869
extension Collection {
@@ -73,9 +74,11 @@ extension Collection {
7374
public func chunked<Subject: Equatable>(
7475
on projection: (Element) -> Subject
7576
) -> [(Subject, SubSequence)]
77+
78+
public func chunks(ofCount count: Int) -> ChunksOfCountCollection<Self>
7679
}
7780

78-
extension LazyCollectionProtocol {
81+
extension LazySequenceProtocol where Self: Collection, Elements: Collection {
7982
public func chunked(
8083
by belongInSameGroup: @escaping (Element, Element) -> Bool
8184
) -> ChunkedByCollection<Elements, Element>
@@ -86,8 +89,10 @@ extension LazyCollectionProtocol {
8689
}
8790
```
8891

89-
The `ChunkedByCollection` and `ChunkedOnCollection` types are bidirectional when
90-
the wrapped collection is bidirectional.
92+
The `ChunkedByCollection`, `ChunkedOnCollection`, and `ChunksOfCountCollection`
93+
types are bidirectional when the wrapped collection is bidirectional.
94+
`ChunksOfCountCollection` also conforms to `LazySequenceProtocol` when the base
95+
collection conforms.
9196

9297
### Complexity
9398

Guides/Compacted.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ extension Collection {
3737

3838
The `Sequence` version of `compacted()` returns a `CompactedSequence` type,
3939
while the `Collection` version returns `CompactedCollection`. The collection
40-
has conditional conformance to `BidirectionalCollection` and
41-
`LazyCollectionProtocol` when the base collection conforms.
40+
has conditional conformance to `BidirectionalCollection` when the base
41+
collection conforms, and both have conditional conformance to
42+
`LazySequenceProtocol` when the base collection conforms.
4243

4344
### Naming
4445

Guides/Indexed.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ for (i, n) in numbers.indexed() {
2121

2222
## Detailed Design
2323

24-
The `indexed` method returns an `Indexed` type:
24+
The `indexed` method returns an `IndexedCollection` type:
2525

2626
```swift
2727
extension Collection {
@@ -31,5 +31,5 @@ extension Collection {
3131

3232
`IndexedCollection` scales from a collection up to a random-access collection,
3333
depending on its base type. `Indexed` also conforms to `LazySequenceProtocol`
34-
and `LazyCollectionProtocol` when the base type conforms.
34+
when the base type conforms.
3535

Guides/Intersperse.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ extension Sequence {
3131

3232
The new `InterspersedSequence` type represents the sequence when the separator
3333
is inserted between each element. `InterspersedSequence` conforms to
34-
`Collection`, `BidirectionalCollection`, `RandomAccessCollection`,
35-
`LazySequenceProtocol` and `LazyCollectionProtocol` when the base sequence
36-
conforms to those respective protocols.
34+
`Collection`, `BidirectionalCollection`, `RandomAccessCollection` and
35+
`LazySequenceProtocol` when the base sequence conforms to those respective
36+
protocols.
3737

3838
### Complexity
3939

Guides/Joined.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ Note that the sequence separator of the closure-less version defined on
7070
general be iterated over multiple times.
7171

7272
The closure-based versions also have lazy variants that are defined on both
73-
`LazySequenceProtocol` and `LazyCollectionProtocol` for the same reason as
74-
explained above:
73+
lazy sequences and collections for the same reason as explained above:
7574

7675
```swift
7776
extension LazySequenceProtocol where Element: Sequence {
@@ -84,7 +83,7 @@ extension LazySequenceProtocol where Element: Sequence {
8483
) -> JoinedByClosureSequence<Self, Separator>
8584
}
8685

87-
extension LazyCollectionProtocol where Element: Collection {
86+
extension LazySequenceProtocol where Self: Collection, Element: Collection {
8887
public func joined(
8988
by separator: @escaping (Element, Element) -> Element.Element
9089
) -> JoinedByClosureCollection<Self, CollectionOfOne<Element.Element>>
@@ -98,5 +97,4 @@ extension LazyCollectionProtocol where Element: Collection {
9897
`JoinedBySequence`, `JoinedByClosureSequence`, `JoinedByCollection`, and
9998
`JoinedByClosureCollection` conform to `LazySequenceProtocol` when the base
10099
sequence conforms. `JoinedByCollection` and `JoinedByClosureCollection` also
101-
conform to `LazyCollectionProtocol` and `BidirectionalCollection` when the base
102-
collection conforms.
100+
conform to `BidirectionalCollection` when the base collection conforms.

Guides/Permutations.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,15 @@ Since both result types need to store an array of the collection’s
120120
indices and mutate the array to generate each permutation, they only
121121
have `Sequence` conformance. Adding `Collection` conformance would require
122122
storing the array in the index type, which would in turn lead to copying the
123-
array at every index advancement. The `PermutationsSequence` type
124-
conforms to `LazySequenceProtocol` when its base type conforms.
123+
array at every index advancement. The `PermutationsSequence` and
124+
`UniquePermutationsSequence` types conforms to `LazySequenceProtocol` when their
125+
base type conforms.
125126

126127
### Complexity
127128

128129
Calling `permutations()` is an O(1) operation. Creating the iterator for a
129-
`Permutations` instance and each call to `Permutations.Iterator.next()` is an
130-
O(_n_) operation.
130+
`PermutationsSequence` instance and each call to
131+
`PermutationsSequence.Iterator.next()` is an O(_n_) operation.
131132

132133
Calling `uniquePermutations()` is an O(_n_) operation, because it preprocesses
133134
the collection to find duplicate elements. Creating the iterator for and each

Guides/Product.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ collection, and a random-access collection when both base collections have those
4343
conformances.
4444

4545
We don't provide higher arities (like `Product3Sequence`, `Product4Sequence`,
46-
etc.) at this time to match the standard library's `Zip2` type. Users can
47-
compose multiple calls to `product` if they would like higher arities.
46+
etc.) at this time to match the standard library's `Zip2Sequence` type. Users
47+
can compose multiple calls to `product` if they would like higher arities.
4848

4949
### Complexity
5050

Guides/LazySplit.md renamed to Guides/Split.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# LazySplit
1+
# Split
22

3-
[[Source](https://github.com/apple/swift-algorithms/blob/main/Sources/Algorithms/LazySplit.swift) |
4-
[Tests](https://github.com/apple/swift-algorithms/blob/main/Tests/SwiftAlgorithmsTests/LazySplitTests.swift)]
3+
[[Source](https://github.com/apple/swift-algorithms/blob/main/Sources/Algorithms/Split.swift) |
4+
[Tests](https://github.com/apple/swift-algorithms/blob/main/Tests/SwiftAlgorithmsTests/SplitTests.swift)]
55

66
Lazily-evaluating versions of
77
[`split(maxSplits:omittingEmptySubsequences:whereSeparator:)`](https://developer.apple.com/documentation/swift/sequence/3128814-split)

Guides/Stride.md

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,44 @@
33
[[Source](https://github.com/apple/swift-algorithms/blob/main/Sources/Algorithms/Stride.swift) |
44
[Tests](https://github.com/apple/swift-algorithms/blob/main/Tests/SwiftAlgorithmsTests/StrideTests.swift)]
55

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.
77

88
This is available through the `striding(by:)` method on any `Sequence`.
99

1010
```swift
1111
(0...10).striding(by: 2) // == [0, 2, 4, 6, 8, 10]
1212
```
1313

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.
1616

1717
The stride amount must be a positive value.
1818

1919
## Detailed Design
2020

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`:
2323

2424
```swift
2525
extension Sequence {
26-
public func striding(by step: Int) -> StridingSequence<Self>
26+
public func striding(by step: Int) -> StridingSequence<Self>
2727
}
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.
3228

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+
}
3632
```
3733

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+
3844
A careful thought was given to the composition of these strides by giving a
3945
custom implementation to `index(_:offsetBy:limitedBy)` which multiplies the
4046
offset by the stride amount.

Guides/Windows.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ collection is empty.
3636

3737
The resulting `WindowsCollection` type is a collection, with conditional
3838
conformance to the `BidirectionalCollection`, `RandomAccessCollection`, and
39-
`LazyCollectionProtocol` protocols when the base collection conforms.
39+
`LazySequenceProtocol` protocols when the base collection conforms.
4040

4141
### Complexity
4242

0 commit comments

Comments
 (0)