Fra*_*cis 5 kotlin kotlin-coroutines kotlin-coroutines-flow
有zip功能可以压缩两个Flows
。有什么东西可以将三个(或更多)压缩Flows
在一起吗?
如果没有,你能帮我实现它的扩展功能吗?就像是:
flow.zip(flow2, flow3) { a, b, c ->
}
Run Code Online (Sandbox Code Playgroud)
我没有测试过这个,但你可以尝试一下。有很多底层代码zip
,因此为了利用它,我将前两个流压缩成一个对流,然后将对流压缩到第三个流。但是传递给该函数的 lambda 得到的前两个已经分开,因此它不必知道中间的 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)
}
Run Code Online (Sandbox Code Playgroud)
用法如下:
zip(flow1, flow2, flow3) { a, b, c ->
Triple(a, b, c)
}
Run Code Online (Sandbox Code Playgroud)
这是针对任意数量的流的未经测试的版本,但它们必须是相同的类型:
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)
}
}
Run Code Online (Sandbox Code Playgroud)