Is there an operator to combine the latest values ...
# coroutines
r
Is there an operator to combine the latest values from a
List<Flow<T>>
? Something that would have this signature
(List<Flow<T>>) -> Flow<List<T>>
? I’m updating a RecyclerView using
AsyncListDiffer.submitIList()
.
t
Flow is not a collection, so I think you'll have to implement a mechanism to remember recent values yourself.
r
There are Rx operators for this transformation so I was hoping Flow came with batteries 😉
My first attempt.
m
You can use something like this.
Copy code
internal fun <T> Iterable<Flow<T>>.combineLatest(): Flow<List<T>> {
  val emptyFlow = emptyFlow<List<T>>()
  return fold(emptyFlow) { xs, x ->
    if (xs === emptyFlow) {
      x.map(::listOf)
    } else {
      xs.combine(x) { a, b -> a + b }
    }
  }
}
r
Impressive but it doesn’t quite behave correctly for me. I’m not sure why. My implementation also doesn’t work 😕
m
What doesn't work? What is the incorrect behavior?
r
For some reason I only get the first value after one of the flows completes.
I’m dealing with other bugs so it might not be this code
d
I think you want
combine(....) {...}
.
r
It works as expected. It was just stupid Retrofit/OkHttp blocking preventing multiple concurrent requests.
This is another version that works. But I don’t think these are efficient. Is there an implementation is easy to reason about and reasonably efficient?
d
Copy code
fun <T> Iterable<Flow<T>>.combineLatest(): Flow<List<T>> = combine(this) { it.toList() }
👍 2
m
Oh nice. I wasn’t aware of an overload that accepts an iterable.