简体   繁体   中英

RxSwift: Combining different types of observables and mapping result

I am pretty new to RxSwift and stuck in creating a sequence.

I have 3 observables (isChanged, updatedValue, savedValue). If form value isChanged I want to use updatedValue otherwise savedValue. I tried using .combineLatest as

Observable.combineLatest( isChanged, updatedValue, savedValue,
resultSelector: {isChanged, updatedValue, savedValue in
   print ("\(isChanged), \(updatedValue), \(savedValue)")
 }.observeOn(MainSchedular.instance)
  .subscribe()
  .disposed(by: bag)

I want to use updatedValue only if isChanged flag is changed otherwise always use savedValue.

I tried using flatMapLatest as well but I am struggling with syntax too. Any help will be appreciated. TIA

Your comment describes a different use-case than what the question describes...

updatedValue is changed with every key strike, isChanged is called only when update button is tapped while savedValue is orignal value.

The above implies that you want something like:

func example<Value>(savedValue: Value, isChanged: Observable<Void>, updatedValue: Observable<Value>) -> Observable<Value> {
    isChanged
        .withLatestFrom(updatedValue)
        .startWith(savedValue)
}

The above will emit the savedValue , then emit whatever was last emitted by updatedValue every time isChanged emits. I suggest you change the name of isChanged to something else since it isn't a Bool.

Meanwhile, the question implies that you want something more like:

func exampleʹ<Value>(savedValue: Value, isChanged: Observable<Bool>, updatedValue: Observable<Value>) -> Observable<Value> {
    isChanged
        .withLatestFrom(updatedValue) { $0 ? savedValue : $1 }
}

The above will also emit a value every time isChanged emits a value. It will emit savedValue whenever isChanged emits false and updatedValue whenever isChanged emits true.


If savedValue is an Observable (maybe from a network request or a DB get) then the code would look more like this:

func example<Value>(isChanged: Observable<Void>, savedValue: Observable<Value>, updatedValue: Observable<Value>) -> Observable<Value> {
    savedValue
        .concat(
            isChanged.withLatestFrom(updatedValue)
        )
}

func exampleʹ<Value>(isChanged: Observable<Bool>, savedValue: Observable<Value>, updatedValue: Observable<Value>) -> Observable<Value> {
    isChanged
        .withLatestFrom(Observable.combineLatest(savedValue, updatedValue)) { $0 ? $1.0 : $1.1 }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM