Search code examples
observablereactive-programmingrx-swiftreactive

Operator with two last elements from Observable in RxSwift


I have an observable sequence of Ints:

-1-2-3-4-5-6-3-4-5-1-

For example, I need to detect when the previous element was bigger than the last one.

In this sequence it's (6, 3) and (5, 1):

-1-2-3-4-5-6-3-4-5-1-
-------------ˆ-----ˆ-

Which operator I can use in this case?


Solution

  • Yes scan is operator you looking for:

    let stream = Observable<Int>.from([1, 2, 3, 4, 5, 6, 3, 4, 5, 1])
    let seed = (0, 0) // (any Int, Int that smaller of all possible values of first emited Int)
    let wrongPairs = stream
        .scan(seed) { last, new -> (Int, Int) in
            return (last.1, new)
        }
        .filter { $0.0 > $0.1 }
    

    With scan we map stream of Ints to stream of Int pairs and then filter all pairs that are "good" (previous element if smaller or equal):

    -1-2-3-4-5-6-3-4-5-1-
    -(0, 1)-(1, 2)-(2, 3)-(3, 4)-(4, 5)-(5, 6)-(6, 3)-(3, 4)-(4, 5)-(5, 1)-
    -(6, 3)-(5, 1)-
    

    Disadvantage of scan that you need initial number to start with, which can be problematic in some cases, but if your stream always emit positive numbers -1 will work.