Which RxSwift operator to use for uniquely emitted elements and how to?

Daniyal Raza :
location.filter({$0.speed < 25})
.debounce(.seconds(20), scheduler: MainScheduler.instance)
.subscribe(onNext: { (location) in
    print(location)
}).disposed(by: disposeBag)

Goals:

  1. If the speed property remains below 25 for 20 seconds then print location
  2. If within 20 seconds speed goes above 25 cancel the emitted event
  3. If the speed remains below 25 for 40 seconds, location should be printed twice once at 20 seconds and again at 40 seconds.

Current problem is : If the speed goes below 25 and within 20 seconds observable receives a second event with speed below 25 it cancels out the previous event because of debounce.

hell0friend :

You should add the distinctUntilChanged operator:

location.distinctUntilChanged { $0.speed < 25 && $1.speed < 25 }
    .debounce(.seconds(20), scheduler: MainScheduler.instance)
    .filter { $0.speed < 25 }
    .subscribe(onNext: { location in
        print(location)
    })
    .disposed(by: disposeBag)

EDIT Case when location should be printed every 20 seconds if speed is less than 25:

let isSpeedBelow = location
    .distinctUntilChanged { $0.speed < 25 && $1.speed < 25 }
    .flatMapLatest { location -> Observable<Double> in
        if location.speed >= 25 {
            return Observable.just(location)
        }
        return Observable<Int>.timer(.seconds(10), period: nil, scheduler: MainScheduler.instance)
            .map { _ in location.speed }
    }
    .map { $0 < 25 }
    .startWith(true)

Observable<Int>.timer(.seconds(10), period: .seconds(10), scheduler: MainScheduler.instance)
    .withLatestFrom(isSpeedBelow)
    .filter { $0 }
    .withLatestFrom(location)
    .subscribe(onNext: { location in
        print(location)
    })
    .disposed(by: disposeBag)

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=390851&siteId=1