2
votes

In my application I have two Flows of data which I want to combine into a single one containing a pair of the values. However, when Flow A emits a new value the combined Flow should emit a pair with a null value until Flow B emits a new value. Think of it like this:

Flow A    A --------------------------> B --------------------------> C ----->
Flow B    1 ---------> 2 ------------------------> 3 ----> 4 --------------> 5

Result    A1 --------> A2 ------------> Bn ------> B3 ---> B4 ------> Cn --> C5

Where n stands for the null value. How can I create this behaviour? Is there maybe an extension function for this on Flow similar to zip or so?

1
Perhaps Flow B should be a Channel? - Some random IT boy

1 Answers

0
votes

I don't think there's a simple way to do this with existing flow operators, but you can roll your own by building a new flow.

fun <A, B> combineWithNulls(flowA: Flow<A>, flowB: Flow<B>) = flow {
    var previousB: B? = null
    combine(flowA, flowB) { a, b -> a to b }.collect { (a, b) ->
        if (b == previousB) {
            emit(a to null)
        } else {
            previousB = b
            emit(a to b)
        }
    }
}

First we use the combine operator to create a flow that emits a new pair each time either flow emits an item. Then we collect the combined flow, and compare the value from flowB against a value that's stored in a variable our new flow. If the values match, we emit a null. Otherwise, we emit the real value and updated the stored value.