简体   繁体   中英

How to ignore behaviorRelay element removal on RxSwift?

I'm observing a BehaviorRelay and I want to subscribe only when the number of items increase. I tried distinct/dinstinctUntilChanged but it does not suit my needs because it will skip too much or too few times.

behaviorRelay
  .compactMap { $0?.items }
  .subscribe(onNext: { elements in
      print("items has one more element.")
  }).disposed(by: bag)

var behaviorRelay = BehaviorRelay<[Car]?>(value: [])

class Car {
  var items: [Any] // whatever... just an example.
}

First of all, use map to map from array to number (of elements):

.map { $0?.count ?? 0 } // return 0 if array is nil

Than use scan , to retrieve both current and previous element, like this:

.scan((0, 0)) { previousPairOfValues, newValue in
    return (previousPairOfValues.1, newValue) // create new pair from newValue and second item of previous pair
}

Then use filter , to only pass increasing values:

.filter { $0.1 > $0.0 } // newer value greater than older value

Than map it back to the latest value:

.map { $0.1 }

Putting all together:

behaviorRelay
  .compactMap { $0?.items }
  .map { $0?.count ?? 0 } // return 0 if array is nil
  .scan((0, 0)) { previousPairOfValues, newValue in
    return (previousPairOfValues.1, newValue) // create new pair from newValue and second item of previous pair
  }
  .filter { $0.1 > $0.0 } // newer value greater than older value
  .map { $0.1 }
  .subscribe(onNext: { elementCount in
      print("items has one more element.")
      print("there are \(elementCount) items now")
  }).disposed(by: bag)

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