Skip to content

Instantly share code, notes, and snippets.

@danielt1263
Last active February 22, 2023 03:08
Show Gist options
  • Save danielt1263/ec1032375498eb95aa260239b289d263 to your computer and use it in GitHub Desktop.
Save danielt1263/ec1032375498eb95aa260239b289d263 to your computer and use it in GitHub Desktop.
//
// EmitWhile.swift
//
// Created by Daniel Tartaglia on 09/06/2018.
// Copyright © 2021 Daniel Tartaglia. MIT License.
//
import Foundation
import RxSwift
/**
Calls `producer` with `seed` then emits result and also passes it to `pred`. Will continue to call
`producer` with new values as long as `pred` returns values.
- parameter seed: The starting value needed for the first producer call.
- parameter pred: A closure that determines the next value pass into the producer or returns nil if no
more calls are necessary.
- parameter producer: A closure that returns a Single.
- returns: An observable that emits each producer's value.
*/
func emitWhile<T, U>(seed: U, pred: @escaping (T) -> U?, producer: @escaping (U) -> Single<T>) -> Observable<T> {
producer(seed)
.asObservable()
.flatMap { (result) -> Observable<T> in
guard let value = pred(result) else { return .just(result) }
return emitWhile(seed: value, pred: pred, producer: producer)
.startWith(result)
}
}
@AbeiOS
Copy link

AbeiOS commented Mar 10, 2021

cool!

@danielt1263
Copy link
Author

Many thanks to @cjspradling on the RxSwift slack for ideas on refinement!

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