Skip to content

Instantly share code, notes, and snippets.

@daltonclaybrook
Last active July 4, 2022 10:41
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save daltonclaybrook/061fa4a8147bfdf69196652285192982 to your computer and use it in GitHub Desktop.
Save daltonclaybrook/061fa4a8147bfdf69196652285192982 to your computer and use it in GitHub Desktop.
import Combine
struct ZipMany<Element, Failure>: Publisher where Failure: Error {
typealias Output = [Element]
private let underlying: AnyPublisher<Output, Failure>
init<T: Publisher>(publishers: [T]) where T.Output == Element, T.Failure == Failure {
let zipped: AnyPublisher<[T.Output], T.Failure>? = publishers.reduce(nil) { result, publisher in
if let result = result {
return publisher.zip(result).map { element, array in
array + [element]
}.eraseToAnyPublisher()
} else {
return publisher.map { [$0] }.eraseToAnyPublisher()
}
}
underlying = zipped ?? Publishers.Empty(completeImmediately: false)
.eraseToAnyPublisher()
}
func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input {
underlying.receive(subscriber: subscriber)
}
}
@danielt1263
Copy link

I would expect a ZipMany(publishers: [AnyPublisher<Int, Error>]()) to complete but otherwise this is a great implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment