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



函数soundDbFlow生成一个与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 Stream API中有一个不错的DoubleSummaryStatistics类。除了缺少包含最新处理值(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) }
}

最新更新