如何计算Elixir中列表的累计金额?

时间:2017-05-07 12:28:04

标签: elixir reduce cumulative-sum

我有一个小组列表:

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

我需要计算它们的累积总和,得到:

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

尝试使用Enum.reduce,但我还不知道如何将新列表作为累加器返回,我是否应该使用列表的尾部来获取最后一个组并从中获取最后一个数量,或者有更好的方法?

2 个答案:

答案 0 :(得分:5)

这是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]]

答案 1 :(得分:0)

也许我没有理解你的观点,所以我根据你的需要准备了两个答案。

<强> 1。列表清单,第二个值是累计金额

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

 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)