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)