简体   繁体   English

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

[英]Elixir Get Map containing maximum values of specific field

I'm a beginner in Elixir programming language. 我是Elixir编程语言的初学者。

I have an object something like this: 我有一个类似这样的对象:

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

let's say my_type is one of ~w[ABCD] 假设my_typemy_type ~w[ABCD]

I want to write a function which takes a list of these objects and returns a following map: 我想编写一个函数,其中包含这些对象的列表并返回以下映射:

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

The values here has to be the MAXIMUM difference between updated_at and created_at columns( Timex.diff(updated_at, created_at, :seconds) ) per my_type + any in addition. 此处的值必须是每个my_type + any其他updated_atcreated_at列之间的最大差异( Timex.diff(updated_at, created_at, :seconds) )。 In case of any the my_type is not considered and takes the maximum among all objects in the list. any情况下,均不考虑my_type并在列表中的所有对象中使用my_type的最大值。

What is the best way to do it in Elixir? 在Elixir中做这件事的最好方法是什么? Thanks. 谢谢。

The following will group the list by its type, then calculate the max difference for each group, and finally result in a map containing each type as the key and max difference as the value. 下面将按列表的类型对列表进行分组,然后计算每个组的最大差异,最后生成一个映射,其中包含每种类型作为键,最大差异作为值。

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

This should give you something like: 这应该给你类似的东西:

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

You can calculate the value for any now by doing map |> Map.values |> Enum.max . 您现在可以通过执行map |> Map.values |> Enum.max来计算any值。

I am posting this here for the sake of formatting and diversity. 我将其张贴在此处是为了格式化和多样化。 The answer by @Dogbert is likely better fit, although this approach could be more straightforward and arguably flexible. @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]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM