What is the fastest / easiest way to calculate a moving average in Kotlin?

I might think of some dirty ways to calculate the moving average on Kotlin, but I'm not sure which one is better. I know that kotlin has many interesting functions for working with collections and lists. What do you think is the most efficient (or easiest) way to calculate a moving average?

+4
source share
1 answer

Kotlin 1.2 will introduce a sliding window that can be combined with average, obviously.

val data = listOf(1,2,5,6,2,7,8,5,9)
// 3 "period" moving average
val movingAverage = data.windowed(3,1,List<Int>::average)
// OR
val movingAverage = data.windowed(3,1) { it.average() }

Until then, you will have to submit your own sliding sequence.

class SlidingSequence<out T>(val source: Iterable<T>,
                                      val slideSize: Int,
                                      val slideStep: Int) : Sequence<List<T>> {
    override fun iterator(): Iterator<List<T>> = object : AbstractIterator<List<T>>() {
        private val iterator = if (slideSize > 0) source.iterator() else emptyList<T>().iterator()
        private var buffer = listOf<T>()

        override fun computeNext() = when {
            iterator.hasNext() -> {
                buffer = buffer.drop(slideStep).let {
                    it + iterator.asSequence().take(slideSize - it.size)
                }
                setNext(buffer)
            }
            else -> done()
        }
    }
}

fun <T> Iterable<T>.windowed(size: Int,
                          step: Int = 1): Sequence<List<T>> {
    return SlidingSequence(this, size, step)
}

// and then you can do
val data = listOf(1,2,5,6,2,7,8,5,9)
// 3 "period" moving average
val movingAverage = data.windowed(3).map(List<Int>::average)

PS. Kotlin 1.2 windowed, , , , , - .toList() .

+7

Source: https://habr.com/ru/post/1685067/


All Articles