Я не проверял это, но вы можете попробовать. Существует много базового кода для zip
, поэтому, чтобы использовать это, я заархивирую первые два потока в поток пар, а затем перенесу поток пар в третий поток. Но лямбда, переданная этой функции, получает первые две уже разделенных, поэтому ей не нужно знать о промежуточном шаге Pair.
fun <T1, T2, T3, R> zip(
first: Flow<T1>,
second: Flow<T2>,
third: Flow<T3>,
transform: suspend (T1, T2, T3) -> R
): Flow<R> =
first.zip(second) { a, b -> a to b }
.zip(third) { (a, b), c ->
transform(a, b, c)
}
Использование так:
zip(flow1, flow2, flow3) { a, b, c ->
Triple(a, b, c)
}
И Вот непроверенная версия для произвольного числа потоков, но они должны быть одного типа:
fun <T, R> zip(
vararg flows: Flow<T>,
transform: suspend (List<T>) -> R
): Flow<R> = when(flows.size) {
0 -> error("No flows")
1 -> flows[0].map{ transform(listOf(it)) }
2 -> flows[0].zip(flows[1]) { a, b -> transform(listOf(a, b)) }
else -> {
var accFlow: Flow<List<T>> = flows[0].zip(flows[1]) { a, b -> listOf(a, b) }
for (i in 2 until flows.size) {
accFlow = accFlow.zip(flows[i]) { list, it ->
list + it
}
}
accFlow.map(transform)
}
}