如何计算 Kotlin 中连续流量的最小值、最大值和平均值?

How can I calculate min, max, average of continuous Flow in Kotlin?

函数soundDbFlow生成了一个double数据连续的Flow,我希望得到这些数据的最大值,主值和平均值,我该怎么做?

代码A是我写的,我觉得不好

代码A

   var countInfo = mutableStateOf(0)
    var currentInfo = mutableStateOf(2.0)
    var aveInfo=  mutableStateOf(5.0)
    var minInfo = mutableStateOf(0.0)
    var maxInfo = mutableStateOf(10.0)

    private var valuesCount = 0
    private var sum = 0.0

    private fun soundDbFlow(period: Long=100) = flow {
          while (true) {
             val data=(0..1000).random().toDouble()
             emit(data)
             delay(period)
          }
    }


    fun calCurrentAsynNew() {
        viewModelScope.launch(Dispatchers.IO) {
            iniInfo()
            soundDbFlow().collect {setInfo(it) }
        }
    }

    private fun iniInfo(){
        valuesCount = 0
        sum = 0.0

        aveInfo.value=0.0

        minInfo.value=0.0
        maxInfo.value=0.0
    }

    private fun setInfo(input: Double) {
        countInfo.value = countInfo.value + 1
        currentInfo.value = input
        if (input > maxInfo.value) maxInfo.value = input
        if (input < maxInfo.value) minInfo.value = input
        sum = sum + input
        valuesCount = valuesCount + 1
        aveInfo.value = sum / valuesCount
    }

Java 流 API 中有一个不错的 DoubleSummaryStatistics class。它看起来几乎与您需要的一样,只是缺少包含最新处理值的字段 (current)。

如果您的目标是 JVM,则可以重用它:

class Stats(val current: Double) : DoubleSummaryStatistics(1, current, current, current) {
    //Override to show newly added `current` field
    override fun toString() = String.format(
        "%s{current=%f, count=%d, sum=%f, min=%f, average=%f, max=%f}",
        javaClass.simpleName, current, count, sum, min, average, max)
}

(否则,只需在纯 Kotlin 中重新实现它,根据您的需要选择定制 API)

Flow一起使用:

suspend fun main() {
    soundDbFlow()
        .map { Stats(it) }
        .runningReduce { acc, value -> value.apply { combine(acc) } }
        .collect { println(it) }
}