Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

152
Visualizações
How can I design a Flow which is a average value of every latest 5 data of another Flow?

There is a Flow which will emit data every 100ms, and I hope to get a average value of every latest 5 data of the Flow, and convert the average value as Double value into another Flow.

How can I design the Flow?

Code A

   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)
    }

Added Content:

To plplmax: Thanks!

I assume Code B will emit 1,2,3,4,5,6,7,8,9,10.....

Do you guarantee Code C will calculate (1+2+3+4+5)/5 first, then calculate (6+7+8+9+10)/5 second, .... ? It's my expectation.

I worry that Code C maybe calculate (1+2+3+4+5)/5 first, the calculate (2+3+4+5+6)/5 sencond, ...

Code B

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

Code C

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)
    }
}
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

You can write a chunked operator like this:

/**
 * 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()
        }
    }
}

And then use it like this:

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) }
over 4 years ago · Santiago Trujillo Relatório

0

Is that what you want?

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) }
}
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda