如何在满足特定条件之前从流中收集项目?
How to collect items from a Flow until a particular condition is met?
我有一个 Flow<List<Int?>>
并且我想收集此流,但只能收集到一个空 Int。然后流程应该被取消。例如,
val flow = flowOf(
listOf(1, 2),
listOf(3, null),
listOf(4)
)
flow.collectUntilNull {
println(it)
}
我想要的输出是:
[1, 2]
[3, null]
我知道有一个函数 Flow.takeWhile
但它不会发出谓词 returns 为假的值。就我而言,我也想要那个。
public fun <T> Flow<T>.takeWhile(predicate: suspend (T) -> Boolean): Flow<T> = flow {
return@flow collectWhile { value ->
if (predicate(value)) {
emit(value)
true
} else {
// I want a "emit(value)" here
false
}
}
}
由于 collectWhile
是内部代码,我无法使用此代码。虽然我想我可以在我的代码中复制粘贴 collectWhile
实现。但是还有其他方法吗?
所以,我发现的一种方式类似于:
var b = true
flow.takeWhile {i -> b.also { b = myCondition(i) } }
.collect {
println(it)
}
把它拿出来作为扩展,
fun <T> Flow<T>.takeUntil(predicate: suspend (T) -> Boolean): Flow<T> {
var b = true
return takeWhile { i ->
b.also { b = predicate(i) }
}
}
// Usage
flow.takeUntil { myCondition(it) }
.collect {
}
有没有更好的方法?
transformWhile
更flexible/generalizedtakeWhile
.
flow
.transformWhile {
emit(it)
myCondition(it)
}
.collect {
println(it)
}
我有一个 Flow<List<Int?>>
并且我想收集此流,但只能收集到一个空 Int。然后流程应该被取消。例如,
val flow = flowOf(
listOf(1, 2),
listOf(3, null),
listOf(4)
)
flow.collectUntilNull {
println(it)
}
我想要的输出是:
[1, 2]
[3, null]
我知道有一个函数 Flow.takeWhile
但它不会发出谓词 returns 为假的值。就我而言,我也想要那个。
public fun <T> Flow<T>.takeWhile(predicate: suspend (T) -> Boolean): Flow<T> = flow {
return@flow collectWhile { value ->
if (predicate(value)) {
emit(value)
true
} else {
// I want a "emit(value)" here
false
}
}
}
由于 collectWhile
是内部代码,我无法使用此代码。虽然我想我可以在我的代码中复制粘贴 collectWhile
实现。但是还有其他方法吗?
所以,我发现的一种方式类似于:
var b = true
flow.takeWhile {i -> b.also { b = myCondition(i) } }
.collect {
println(it)
}
把它拿出来作为扩展,
fun <T> Flow<T>.takeUntil(predicate: suspend (T) -> Boolean): Flow<T> {
var b = true
return takeWhile { i ->
b.also { b = predicate(i) }
}
}
// Usage
flow.takeUntil { myCondition(it) }
.collect {
}
有没有更好的方法?
transformWhile
更flexible/generalizedtakeWhile
.
flow
.transformWhile {
emit(it)
myCondition(it)
}
.collect {
println(it)
}