【问题标题】:How to sum up values of different keys in a list of maps in Elixir如何在 Elixir 的地图列表中总结不同键的值
【发布时间】:2020-12-22 05:01:09
【问题描述】:

您好,我想将所有 count 和所有 val 键汇总到一个包含两个键的累积值的新映射中。

这是我到目前为止所做的:

list = [
  %{count: 1, val: 12},
  %{count: 3, val: 7},
  %{count: 1, val: 5},
  %{count: 2, val: 3},
  %{count: 2, val: 5},
  %{count: 1, val: 3}
]

x = &%{count: &1, val: &1}
sumCount = list |> Enum.reduce(0, &(&1.count + &2)) |> x.() |> IO.inspect()

我得到这个结果:

#ouput: 
%{count: 10, val: 10}

但我需要这个结果:

%{count: 10, val: 35}

我只知道如何总结一个关键。我应该在两个功能中分别总结键吗?我认为这不是性能,考虑到列表将有更多的值/映射或者更多的键。 有没有一种有效的方法来一次总结所有的键?

【问题讨论】:

    标签: elixir reduce


    【解决方案1】:

    我会将初始列表减少Map.merge/3

    Enum.reduce(list, &Map.merge(&1, &2, fn _, v1, v2 -> v1 + v2 end))
    #⇒ %{count: 10, val: 35}
    

    【讨论】:

    • 使用合并冲突解决方法并不比对值求和简单。
    • 它更短,更容易扩展到 100 个键的情况下,并且不依赖于键名,因此更容易重构。有足够的理由投票给它。
    【解决方案2】:

    您可以使用Enum.reduce/2,因为您的列表元素和累积值的格式相同。诀窍是使用整个映射 %{count: count, val: val} 作为累加器,而不仅仅是一个整数:

    Enum.reduce(list, fn item, acc ->
      %{count: item.count + acc.count, val: item.val + acc.val}
    end)
    

    【讨论】:

      【解决方案3】:

      我想这就是你要找的东西?

      Enum.reduce(list, %{count: 0, val: 0}, fn %{count: count, val: val}, acc ->
        %{count: acc.count + count, val: acc.val + val}
      end)
      

      【讨论】:

      • 这里初始累加器是多余的,改用Enum.reduce/2
      • 是的,但我认为这取决于您是否需要处理空情况,在这种情况下reduce/2 无法推断出初始累加器? (Raises Enum.EmptyError if enumerable is empty.)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-18
      • 2017-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多