将Scala流转换为新流,该流是当前元素和前一元素的总和

时间:2014-06-30 07:18:53

标签: scala stream

如何转换整数的Scala流,以便我们有一个新的Stream,其中元素是此元素和前一个元素的总和。

例如,如果输入流是1,2,3,4 ......那么输出流是1,3,5,7。

还有第二个问题,如何使总和使用输出流中的前一个,以便输出为1,(2 +(1)),(3 +(2 + 1)),(4 +(3+(2 + 1)))。

2 个答案:

答案 0 :(得分:7)

只需使用自身的移位版本压缩您的信息流并将两个元素相加。

val s1 = Stream.from(0) // 0, 1, 2, 3, ...
val s2 = Stream.from(1) // 1, 2, 3, 4, ...
val sumOfTwo = s1.zip(s2).map{ case (a,b) => a+b } // 1, 3, 5, 7, ...

要计算总和,只需使用像折叠一样的扫描功能,但在每一步都返回元素。

val totalSum = s1.scan(0)((ctr, el) => ctr + el) // 0, 1, 3, 6, 10, ...

答案 1 :(得分:1)

This answer通过使用累积结果的变量而不是scan()来计算累积和。示例程序:

import scala.collection.immutable.Stream

object Main extends App {
    // 1, 2, 3, ...
    val naturals = Stream.from(1) 

    // cumulative sum (see https://stackoverflow.com/a/8567134/1071311)
    def sumUp(s : Stream[Int], acc : Int = 0) : Stream[Int] =
        Stream.cons(s.head + acc, sumUp(s.tail, s.head + acc))

    val firstFive = sumUp(naturals, 0).take(5)

    firstFive.foreach(println _)
}

输出:

1
3
6
10
15