在Kotlin计算移动平均线的最快/最简单的方法是什么?

时间:2017-09-05 07:27:58

标签: kotlin

我可以考虑用一些肮脏的方法计算Kotlin的移动平均线,但我不确定哪一个是最好的。我知道kotlin有许多有趣的功能来处理集合和列表。您认为计算移动平均线的最有效(或最简单)方法是什么?

1 个答案:

答案 0 :(得分:9)

Kotlin 1.2会引入一个sliding window,你可以明显地与average结合使用。

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

在此之前,您必须引入自己的滑动序列。

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实现的代码,但由于该函数需要立即转换,我猜测结果不是懒惰的,在上面的自我实现的情况下&# 39;一个懒惰的结果,所以你需要用.toList()之类的实际枚举序列来获得实际值。

相关问题