Maciej
05/15/2023, 12:16 PM.zip(Iterable<Flow>)
are there plans to add it?CLOVIS
05/15/2023, 1:28 PMsuspend (List<Any>) -> R
?Maciej
05/15/2023, 2:35 PMMaciej
05/15/2023, 2:35 PMpublic inline fun <reified T, R> combine(
vararg flows: Flow<T>,
crossinline transform: suspend (Array<T>) -> R)
CLOVIS
05/15/2023, 3:14 PMcombine
(they all must have a common super type), then you can just use itephemient
05/15/2023, 3:31 PMMaciej
05/15/2023, 3:31 PMMaciej
05/15/2023, 3:32 PMephemient
05/15/2023, 3:38 PMfun <T> Flow<T>.zip(others: Iterable<Flow<T>>): Flow<List<T>> =
others.fold(map { listOf(it) }) { acc, flow -> acc.zip(flow, List<T>::plus) }
Maciej
05/15/2023, 6:10 PMephemient
05/15/2023, 6:14 PMephemient
05/15/2023, 6:14 PMMaciej
05/16/2023, 8:01 AMephemient
05/16/2023, 8:30 AMfold
sets up all the zip
operations before anything is collected. once collecting starts, it'll pull from all of them. the big inefficiency is that constructing lists by +
is O(N^2)ephemient
05/16/2023, 8:31 AMfun <T> Iterable<Flow<T>>.zip(): Flow<List<T>> = flow {
coroutineScope {
val job = Job(coroutineContext.job)
val channels = map { it.buffer(Channel.RENDEZVOUS).produceIn(this + job) }
try {
while (true) emit(channels.map { it.receiveCatching().onClosed { return@coroutineScope }.getOrThrow() })
} finally {
job.cancel()
}
}
}
but I have a hard time coming up with scenarios where you'd use zip
on a wide enough collection of flows for it to really matterMaciej
05/16/2023, 11:42 AMephemient
05/19/2023, 3:50 AM