Finding unique values in a nested keyword list

Hi, i have a nested list and from this list in want to find unique tuples only. For example, in the following list only the unique tuples having larger values will stay and other will be discarded.

list 1:

[
a: [
  b: [ 
   c: [
    {:d, "id_1", 2},
    {:d, "id_1", 1},
    {:d, "id_2", 1},
    {:d, "id_3", 1}
  ]
  c: [
    {:d, "id_3", 2}, 
    {:d, "id_3", 5}
]]]]

final output:

[
a: [
  b: [ 
   c: [
    {:d, "id_1", 2},
    {:d, "id_2", 1},
    {:d, "id_3", 1}
  ]
  c: [
     {:d, "id_3", 5}
]]]]

You can start with a simple list… nesting like this just add some complexities.

And look at the Enum module, maybe there will be something starting like… uniq

The core idea is to use a group_by once you’re looking at the specific keys you care about, then max_by finds the largest. Here’s one approach:

iex(37)> list1
[
  a: [
    b: [
      c: [{:d, "id_1", 2}, {:d, "id_1", 1}, {:d, "id_2", 1}, {:d, "id_3", 1}],
      c: [{:d, "id_3", 2}, {:d, "id_3", 5}]
    ]
  ]
]
iex(38)> update_in(list1, [:a, :b], fn cs ->
...(38)>   Enum.map(cs, fn {k, list} ->
...(38)>     {k,
...(38)>      list
...(38)>      |> Enum.group_by(fn {a, b, _} -> {a, b} end)
...(38)>      |> Enum.map(fn {_, group} -> Enum.max_by(group, &elem(&1, 2)) end)
...(38)>     }
...(38)>   end)
...(38)> end)
[
  a: [
    b: [
      c: [{:d, "id_1", 2}, {:d, "id_2", 1}, {:d, "id_3", 1}],
      c: [{:d, "id_3", 5}]
    ]
  ]
]

I don’t recommend you use this in production until you understand each step. Throw in some IO.inspect calls and step through it.

1 Like