英文:
Sample Flow with last item
问题
Sample from Kotlin Coroutine: 来自Kotlin Coroutine的示例 https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/sample.html
Doesn't emit the last element if the parent flow is finished before the time frame.:如果父流在时间窗口之前完成,则不会发出最后一个元素。
From Docs: 来自文档:
Note that the latest element is not emitted if it does not fit into the sampling window.
:请注意,如果最新元素不适合抽样窗口,则不会发出。
I want an operator that acts just as the sample but emits the last value when the timeframe reaches.:我想要一个操作符,与抽样相同,但在时间窗口到达时发出最后一个值。
The last value is important in my case.:在我的情况下,最后一个值很重要。
Eg code: 例如代码:
val k = (0..100).asFlow().onEach {
delay(200)
}
val k2 = k.sample(500)
k2.collectLatest {
println(it)
}
A custom operator would do if none is provided by the library.:如果库中没有提供操作符,可以使用自定义操作符。
英文:
Sample from Kotlin Coroutine https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/sample.html
Doesn't emit the last element if the parent flow is finished before the time frame.
From Docs:
Note that the latest element is not emitted if it does not fit into the sampling window.
I want an operator that acts just as the sample but emits the last value when the timeframe reaches.
The last value is important in my case.
Eg code:
val k = (0..100).asFlow().onEach {
delay(200)
}
val k2 = k.sample(500)
k2.collectLatest {
println(it)
}
A custom operator would do if none is provided by the library.
答案1
得分: 1
你可以尝试这个。这段代码应该是不言自明的。我没有严格测试过它!
fun <T> Flow<T>.sampleAndKeepLast(periodMillis: Long): Flow<T> {
require(periodMillis > 0) { "Sample period should be positive" }
return channelFlow {
var isDone = false
val empty = Any()
var lastValue: Any? = empty
onEach { lastValue = it }
.onCompletion { isDone = true }
.launchIn(this)
while (!isDone) {
delay(periodMillis)
if (lastValue !== empty) {
@Suppress("UNCHECKED_CAST")
send(lastValue as T)
lastValue = empty
}
}
if (lastValue !== empty) {
@Suppress("UNCHECKED_CAST")
send(lastValue as T)
}
}
}
英文:
You can try this. The code should be self-explanatory. I did not rigorously test it!
fun <T> Flow<T>.sampleAndKeepLast(periodMillis: Long): Flow<T> {
require(periodMillis > 0) { "Sample period should be positive" }
return channelFlow {
var isDone = false
val empty = Any()
var lastValue: Any? = empty
onEach { lastValue = it }
.onCompletion { isDone = true }
.launchIn(this)
while (!isDone) {
delay(periodMillis)
if (lastValue !== empty) {
@Suppress("UNCHECKED_CAST")
send(lastValue as T)
lastValue = empty
}
}
if (lastValue !== empty) {
@Suppress("UNCHECKED_CAST")
send(lastValue as T)
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论