Skip to content

Commit 1eb52b9

Browse files
committed
Add some brief prose for RemoveDuplicates
1 parent 9e4b14a commit 1eb52b9

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

Guides/RemoveDuplicates.md

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@
99

1010
## Introduction
1111

12+
When processing values over time it is definitely possible that the same value may occur in a row. When the distinctness of the presence value is not needed it is useful to consider the values over time that are differing from the last. Particularly this can be expressed as removing duplicate values either in the case as they are directly `Equatable` or by a predicate.
13+
1214
## Proposed Solution
1315

16+
The `removeDuplicates()` and `removeDuplicates(by:)` APIs serve this purpose of removing duplicate values that occur. These algorithms test against the previous value and if the latest iteration of the base `AsyncSequence` is the same as the last it invokes `next()` again. The resulting `AsyncRemoveDuplicatesSequence` will ensure that no duplicate values occur next to each other. This should not be confused with only emitting unique new values; where each value is tested against a collected set of values.
17+
1418
```swift
1519
extension AsyncSequence where Element: Equatable {
1620
public func removeDuplicates() -> AsyncRemoveDuplicatesSequence<Self>
@@ -27,8 +31,14 @@ extension AsyncSequence {
2731
}
2832
```
2933

34+
The `removeDuplicates` family comes in three variants. One variant is conditional upon the `Element` type being `Equatable`. This variation is a shorthand for writing `.removeDuplicates { $0 == $1 }`. The next variation is the closure version that allows for custom predicates to be applied. This algorithm allows for the cases where the elements themselves may not be equatable but portions of the element may be compared. Lastly is the variation that allows for comparison when the comparison method may throw.
35+
3036
## Detailed Design
3137

38+
In the cases where the `Element` type is `Equatable` or the non-trowing predicate variant these utilize the type `AsyncRemoveDuplicatesSequence`. The throwing predicate variant uses `AsyncThrowingRemoveDuplicatesSequence`. Both of these types are conditionally `Sendable` when the base, base element, and base iterator are `Sendable`
39+
40+
The `AsyncRemoveDuplicatesSequence` will rethrow if the base asynchronous sequence throws and will not throw if the base asynchronous sequence does not throw.
41+
3242
```swift
3343
public struct AsyncRemoveDuplicatesSequence<Base: AsyncSequence>: AsyncSequence {
3444
public typealias Element = Base.Element
@@ -42,6 +52,18 @@ public struct AsyncRemoveDuplicatesSequence<Base: AsyncSequence>: AsyncSequence
4252
}
4353
}
4454

55+
extension AsyncRemoveDuplicatesSequence: Sendable
56+
where Base: Sendable, Base.Element: Sendable, Base.AsyncIterator: Sendable { }
57+
58+
extension AsyncRemoveDuplicatesSequence.Iterator: Sendable
59+
where Base: Sendable, Base.Element: Sendable, Base.AsyncIterator: Sendable { }
60+
61+
```
62+
63+
The `AsyncThrowingRemoveDuplicatesSequence` will rethrow if the base asynchronous sequence throws and still may throw if the base asynchronous sequence does not throw due to the predicate having the potential of throwing.
64+
65+
```swift
66+
4567
public struct AsyncThrowingRemoveDuplicatesSequence<Base: AsyncSequence>: AsyncSequence {
4668
public typealias Element = Base.Element
4769

@@ -52,12 +74,6 @@ public struct AsyncThrowingRemoveDuplicatesSequence<Base: AsyncSequence>: AsyncS
5274
public func makeAsyncIterator() -> Iterator
5375
}
5476

55-
extension AsyncRemoveDuplicatesSequence: Sendable
56-
where Base: Sendable, Base.Element: Sendable, Base.AsyncIterator: Sendable { }
57-
58-
extension AsyncRemoveDuplicatesSequence.Iterator: Sendable
59-
where Base: Sendable, Base.Element: Sendable, Base.AsyncIterator: Sendable { }
60-
6177
extension AsyncThrowingRemoveDuplicatesSequence: Sendable
6278
where Base: Sendable, Base.Element: Sendable, Base.AsyncIterator: Sendable { }
6379

@@ -68,6 +84,10 @@ extension AsyncThrowingRemoveDuplicatesSequence.Iterator: Sendable
6884

6985
## Alternatives Considered
7086

87+
An alternative algorithm for uniqueness was considered but was discounted since it does not directly belong to this particular family of methods.
88+
89+
The name of this method could be considered to belong to the `filter` family and could refer directly to the repetitions. There is distinct merit to considering the name to be `filterRepetitions` or `removeRepetitions`. Likewise the terminology of `drop` also has merit.
90+
7191
## Credits/Inspiration
7292

7393
The Combine framework has a [function for publishers](https://developer.apple.com/documentation/combine/publisher/removeduplicates()/) that performs a similar task.

0 commit comments

Comments
 (0)