Elixir获取包含特定字段最大值的地图

时间:2017-11-13 17:35:25

标签: functional-programming elixir

我是Elixir编程语言的初学者。

我有一个像这样的对象:

{
  id: uuid,
  created_at: DateTime.t,
  updated_at: DateTime.t,
  type: my_type
}

我们说my_type~w[A B C D]

之一

我想编写一个函数,它接受这些对象的列表并返回以下映射:

%{
  A: 120,
  B: 220,
  C: 560,
  D: 0,
  any: 560
} 

此处的值必须是updated_atcreated_at列之间的最大差异(Timex.diff(updated_at, created_at, :seconds)my_type + any。 如果any不考虑my_type,则在列表中的所有对象中取最大值。

在Elixir中进行此操作的最佳方式是什么?感谢。

2 个答案:

答案 0 :(得分:4)

以下内容将按类型对列表进行分组,然后计算每个组的最大差异,最后得到一个包含每个类型作为键的映射,并将最大差值作为值。

map = list
|> Enum.group_by(& &1.type)
|> Enum.map(fn {type, values} ->
  max =
    values
    |> Enum.map(fn %{created_at: created_at, updated_at: updated_at} ->
      # return the difference here
    end)
    |> Enum.max
  {type, max}
end)
|> Map.new

这应该给你类似的东西:

%{
  A: 120,
  B: 220,
  C: 560,
  D: 0
}

您可以通过执行any来计算map |> Map.values |> Enum.max的值。

答案 1 :(得分:1)

我在这里发布这个是为了格式化和多样性。 @Dogbert的答案可能更适合,尽管这种方法可能更直接且可以说是灵活的。

list = [%{type: :a, v1: 10, v2: 20},
        %{type: :a, v1: 10, v2: 30},
        %{type: :b, v1: 10, v2: 20},
        %{type: :c, v1: 10, v2: 20}]

kw = for %{type: t, v1: v1, v2: v2} <- list,
       do: {t, v2 - v1}, into: []
#⇒ [a: 10, a: 20, b: 10, c: 10]

kw
|> Enum.sort_by(fn {_, v} -> v end, &>=/2)
|> Enum.uniq_by(fn {k, _} -> k end)
#⇒ [a: 20, b: 10, c: 10]