如何计算 Elixir 中列表的累计总和?

How to count cumulative sum for a list in Elixir?

我有一个群组列表:

[[10, 1], [11, 1], [13, 3], [15, 10]]

我需要计算他们的累计和,得到:

[[10, 1], [11, 2], [13, 5], [15, 15]].

一直在尝试 Enum.reduce 但我还不知道如何 return 新列表作为累加器,我是否应该从列表的尾部获取最后一组并从还是有更好的方法?

也许我没明白你的意思,所以我根据你的需要准备了两个答案。

1.列表列表,第二个值为累计和

没有 Enum.scan 的解决方案由 Dogbert 提出,非常棒。

 def map_cumulative_sum(list) do
  list
  |> do_map_cumulative_sum([], 0)
 end

defp do_map_cumulative_sum([], acc, _sum_y) do
  Enum.reverse(acc)
end

defp do_map_cumulative_sum([[x, y] | t], acc, sum_y) do
  sum_y = y + sum_y
  do_map_cumulative_sum(t, [ [ x, sum_y] | acc], sum_y)
end

2。结果为

的单个列表

在这种情况下 Enum.reduce 就可以了。

您可以使用带或不带累加器的版本(在这种情况下,累加器将是列表的第一个元素):

list = [[10, 1], [11, 1], [13, 3], [15, 10]]

# reduce list of lists to one list, where 2nd value is cumulative sum
Enum.reduce(list, fn([x, y], [acc_x, acc_y]) -> [x, y + acc_y] end)
> [15, 15]

具有显式累加器的版本只会将 [0, 0] 作为 Enum.reduce 的第二个参数:

Enum.reduce(list, [0, 0], fn([x, y], [acc_x, acc_y]) -> [x, y + acc_y] end)

这是 Enum.scan/2 的完美用例,因为您想收集每次减少的价值:

[[10, 1], [11, 1], [13, 3], [15, 10]]
|> Enum.scan(fn [a, b], [_c, d] ->
  [a, b + d]
end)
|> IO.inspect

输出:

[[10, 1], [11, 2], [13, 5], [15, 15]]