How to filter a list of maps by multi keys?

Hello!
I’m trying to filter list of maps to remove items where value of key was declared previously in this list. List that I have:

list = [
  %{name: "01", type: "t_01", desc: "desc_01_1"},
  %{name: "02", type: "t_02", desc: "desc_02_1"},
  %{name: "01", type: "t_01", desc: "desc_01_2"},
  %{name: "02", type: "t_02", desc: "desc_02_2"}
]

List what I want to get, it should filter by two keys: name and type

list = [
  %{name: "01", type: "t_01", desc: "desc_01_1"},
  %{name: "02", type: "t_02", desc: "desc_02_1"},
]
iex|💧|1 ▸ list |> Enum.group_by(&Map.fetch!(&1, :name)) |> Enum.map(fn {_k, v} -> hd(v) end)
[
  %{name: "01", type: "t_01", desc: "desc_01_1"},
  %{name: "02", type: "t_02", desc: "desc_02_1"}
]

[EDIT] Do not use this. The answer by @roflbobl below is the way to go.

3 Likes

You can do that with Enum.uniq_by/2 like this

iex> list = [
  %{name: "01", type: "t_01", desc: "desc_01_1"},
  %{name: "02", type: "t_02", desc: "desc_02_1"},
  %{name: "01", type: "t_01", desc: "desc_01_2"},
  %{name: "02", type: "t_02", desc: "desc_02_2"}
]

iex> ist = Enum.uniq_by(list, fn elem -> {elem.name, elem.type} end)

iex> [
  %{name: "01", type: "t_01", desc: "desc_01_1"},
  %{name: "02", type: "t_02", desc: "desc_02_1"},
]

You can read more about the function here: Enum.uniq_by/2

5 Likes

Thanks

Thanks