带有最后一项的示例流程

huangapple go评论126阅读模式
英文:

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 &lt;T&gt; Flow&lt;T&gt;.sampleAndKeepLast(periodMillis: Long): Flow&lt;T&gt; {
    require(periodMillis &gt; 0) { &quot;Sample period should be positive&quot; }
    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(&quot;UNCHECKED_CAST&quot;)
                send(lastValue as T)
                lastValue = empty
            }
        }
        if (lastValue !== empty) {
            @Suppress(&quot;UNCHECKED_CAST&quot;)
            send(lastValue as T)
        }
    }
}

huangapple
  • 本文由 发表于 2023年6月13日 18:51:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76464148.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定