Skip to content

Instantly share code, notes, and snippets.

@jasdev
Created February 11, 2021 16:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasdev/00ef4983faf79aa82a2bd3136cc0e2ff to your computer and use it in GitHub Desktop.
Save jasdev/00ef4983faf79aa82a2bd3136cc0e2ff to your computer and use it in GitHub Desktop.
`scan`-based approach to `Publisher.pairwiseWithDuplicatedStart`
// `optionalZip` because `zip` caused ambiguity with `Publisher.zip` in the implementation below.
private func optionalZip<Left, Right>(_ pair: (Left?, Right?)) -> (Left, Right)? {
pair.0.flatMap { left in pair.1.map { right in (left, right) } }
}
extension Publisher {
func pairwiseWithDuplicatedStart() -> AnyPublisher<(Output, Output), Failure> {
scan((nil, nil)) { previousPair, next in
optionalZip(previousPair)
.map { ($0.1, next) } ?? (next, next) // (1)
}
.compactMap(optionalZip)
.eraseToAnyPublisher()
}
}
let cancellable = (1...2)
.publisher
.pairwiseWithDuplicatedStart()
.sink(receiveValue: { print($0) })
// Outputs (without the annotations):
// ```
// (1, 1)
// (1, 2)
// ```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment