首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何设计一个流,它是另一个流的每一个最新的5个数据的平均值?

如何设计一个流,它是另一个流的每一个最新的5个数据的平均值?
EN

Stack Overflow用户
提问于 2022-01-29 02:36:45
回答 2查看 126关注 0票数 3

有一个流,它每100 as发出一次数据,我希望得到该流的每5个最新数据的平均值,并将平均值作为双值转换为另一个流。

我如何设计流程?

码A

代码语言:javascript
复制
   fun soundDbFlow(period: Long = 100) = flow {
        while (true) {
            var data = getAmplitude()
            emit(data)
            delay(period)
        }
    }
    .get_Average_Per5_LatestData {...} //How can I do? or is there other way?
    .map { soundDb(it) }

    private fun getAmplitude(): Int {
        var result = 0
        mRecorder?.let {
            result = it.maxAmplitude
        }
        return result
    }    
        
    private fun soundDb(input:Int, referenceAmp: Double = 1.0): Double {
        return 20 * Math.log10(input / referenceAmp)
    }

添加的内容:

给plplmax:谢谢!

我假设代码B将发射1,2,3,4,5,6,7,8,9,10.

你保证代码C会先计算(1+2+3+4+5)/5,然后计算(6+7+8+9+10)/5第二,.?这是我的期望。

我担心C代码可能首先计算(1+2+3+4+5)/5,计算(2+3+4+5+6)/5感受器,

码B

代码语言:javascript
复制
suspend fun soundDbFlow(period: Long) = flow {
    while (true) {
        val data = getAmplitude()
        emit(data)
        delay(period)
    }
}

代码C

代码语言:javascript
复制
private fun reduceFlow(period: Long = 100) = flow {
    while (true) {
        val result = soundDbFlow(period)
            .take(5)
            .map { soundDb((it / 5.0).roundToInt()) }
            .reduce { accumulator, value -> accumulator + value }
        emit(result)
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-29 12:58:01

您可以编写这样的分块操作符:

代码语言:javascript
复制
/**
 * Returns a Flow that emits sequential [size]d chunks of data from the source flow, 
 * after transforming them with [transform].
 * 
 * The list passed to [transform] is transient and must not be cached.
 */
fun <T, R> Flow<T>.chunked(size: Int, transform: suspend (List<T>)-> R): Flow<R> = flow {
    val cache = ArrayList<T>(size)
    collect {
        cache.add(it)
        if (cache.size == size) {
            emit(transform(cache))
            cache.clear()
        }
    }
}

然后像这样使用它:

代码语言:javascript
复制
suspend fun soundDbFlow(period: Long) = flow {
    while (true) {
        val data = getAmplitude()
        emit(data)
        delay(period)
    }
}
    .chunked(5) { (it.sum() / 5.0).roundToInt() }
    .map { soundDb(it) }
票数 3
EN

Stack Overflow用户

发布于 2022-01-29 07:34:07

这是你想要的吗?

代码语言:javascript
复制
var result = 0

fun soundDbFlow(period: Long) = flow {
    while (true) {
        delay(period)
        val data = getAmplitude()
        emit(data)
    }
}

fun reduceFlow(period: Long = 100) = flow {
    while (true) {
        val sum = soundDbFlow(period)
            .take(5)
            .reduce { accumulator, value -> accumulator + value }

        val average = (sum / 5.0).roundToInt()
        emit(soundDb(average))
    }
}

fun getAmplitude(): Int {
    return ++result
}

fun soundDb(input: Int, referenceAmp: Double = 1.0): Double {
    return 20 * log10(input / referenceAmp)
}

fun main(): Unit = runBlocking {
    reduceFlow().collect { println(it) }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70901974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档