在 Scala 中使用累加器映射列表的功能方法

jus*_*nhj 4 functional-programming scala

我想编写简洁的代码来映​​射一个列表,在我运行时累积一个值并在输出列表中使用该值。

使用递归函数和模式匹配很简单(见下文)。但我想知道是否有一种方法可以使用函数编程系列的组合器(如 map 和 fold 等)来做到这一点。显然 map 和 fold 没有用,除非您使用在调用外部定义的可变变量并在主体中修改它。

也许我可以用 State Monad 来做到这一点,但想知道是否有一种方法可以做到这一点,而我所缺少的就是利用 Scala 标准库。

// accumulate(List(10, 20, 20, 30, 20))
// => List(10, 30, 50, 80, 100,)

def accumulate(weights : List[Int], sum : Int = 0, acc: List[Int] = List.empty) : List[Int] = {
  weights match {
    case hd :: tl =>
      val total = hd + sum
      accumulate(tl, total, total :: acc)
    case Nil =>
      acc.reverse
  }
}
Run Code Online (Sandbox Code Playgroud)

PH8*_*H88 8

您还可以使用foldLeft

def accumulate(seq: Seq[Int]) =
  seq.foldLeft(Vector.empty[Int]) { (result, e) =>
    result :+ result.lastOption.getOrElse(0) + e
  }

accumulate(List(10, 20, 20, 30, 20))
// => List(10, 30, 50, 80, 100,)
Run Code Online (Sandbox Code Playgroud)


Nya*_*vro 7

这可以通过扫描完成:

val result = list.scanLeft(0){case (acc, item) => acc+item}
Run Code Online (Sandbox Code Playgroud)

Scan 会将初始值 0 包含到输出中,因此您必须将其删除:

result.drop(1)
Run Code Online (Sandbox Code Playgroud)