如何计算 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) }
}
函数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) }
}