Skip to content

Instantly share code, notes, and snippets.

@swhitty
Created September 17, 2022 04:47
Show Gist options
  • Save swhitty/ac2d2c77cb856cf37082a26844b66be6 to your computer and use it in GitHub Desktop.
Save swhitty/ac2d2c77cb856cf37082a26844b66be6 to your computer and use it in GitHub Desktop.
extension AsyncSequence where Element: Hashable {
/// Sequence that emits unique elements once each
func unique() -> AsyncUniqueSequence<Self> {
AsyncUniqueSequence(self)
}
}
/// Sequence that only emits unique elements once.
/// While iterating, all emitted elements are retained within a `Set` to ensure uniqueness of each element emitted.
struct AsyncUniqueSequence<Base>: AsyncSequence where Base: AsyncSequence, Base.Element: Hashable {
typealias Element = Base.Element
private let base: Base
init(_ base: Base) {
self.base = base
}
func makeAsyncIterator() -> AsyncIterator {
AsyncIterator(base.makeAsyncIterator())
}
struct AsyncIterator: AsyncIteratorProtocol {
private var iterator: Base.AsyncIterator
private var elements: Set<Base.Element>
init(_ iterator: Base.AsyncIterator) {
self.iterator = iterator
self.elements = []
}
mutating func next() async throws -> Base.Element? {
while let element = try await iterator.next() {
if !elements.contains(element) {
elements.insert(element)
return element
}
}
return nil
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment