数週間前にElixir言語公式スラックのあるスレッドを眺めて学んだテクニックをご紹介します。
TL;DR
defmodule Mnishiguchi.Collection do
@doc """
Averages a list of maps for specified keys.
## Examples
iex> map_list([%{iaq: 123, temp: 28}, %{iaq: 111, temp: 25}], [:iaq])
%{iaq: 117.0}
"""
def avg_maps(map_list, keys) when is_list(map_list) and is_list(keys) do
map_list
# マップから指定されていないキーを取り除く
|> Enum.map(fn x -> Map.take(x, keys) end)
# マップをタプルに変換
|> Enum.flat_map(&Map.to_list/1)
# 各キーでグループ分けをする
|> Enum.group_by(&elem(&1, 0), &elem(&1, 1))
# 各グルーブの値を平均化する
|> Map.new(&{elem(&1, 0), Enum.sum(elem(&1, 1)) / length(elem(&1, 1))})
end
end
例
このようなデータがあったとします。
data = [
%{humi: 85, temp: 35, feeling: "hot"},
%{humi: 47, temp: 25, feeling: "awesome"}
]
平均化したいキーを指定してavg_maps/2
を走らせます。
iex> Mnishiguchi.Collection.avg_maps(data, [:humi, :temp])
%{humi: 66.0, temp: 30.0}
インプットされたデータはこんな感じに加工されていきます。
[%{humi: 85, temp: 35}, %{humi: 47, temp: 25}]
[{:humi, 85}, {:temp, 35}, {:humi, 47}, {:temp, 25}]
%{humi: [85, 47], temp: [35, 25]}
%{humi: 66.0, temp: 30.0}
Wrapping up
- この記事は、2021/07/17(土) 00:00 〜 2021/07/19(月) 23:59開催のautoracex #37という純粋なもくもく会での成果です
- Active Record(Ruby)とEcto(Elixir)でmigrateした内容を一致させる by torifukukaiou
- Elixir言語公式スラックやElixir JPスラックを眺めているといろんなアイデアが見つかります。