useful icon indicating copy to clipboard operation
useful copied to clipboard

A merge_by, kinda group_by

Open ndrean opened this issue 1 year ago • 0 comments

If you find yourself trying to merge maps within a list that share a common key/value, this maybe for you.

From:

[
  %{
    base: "dff3a13e58c2fcb2d1382f8f016e035405bad359",
    full_ref: "#Reference<0.0.575235.90977385.2484928518.78414>",
    full_name: "dff3a13e58c2fcb2d1382f8f016e035405bad359-m1440.webp"
  },
  %{
    base: "dff3a13e58c2fcb2d1382f8f016e035405bad359",
    pred_ref: "#Reference<0.0.575235.90977385.2484928518.78487>",
    ml_name: "dff3a13e58c2fcb2d1382f8f016e035405bad359-m512.webp"
  },
  %{
    base: "dff3a13e58c2fcb2d1382f8f016e035405bad359",
    thumb_ref: "#Reference<0.0.575235.90977385.2484928518.78510>",
    thumb_name: "dff3a13e58c2fcb2d1382f8f016e035405bad359-m200.webp"
  },
  %{
    base: "1110df0436fd62b85bb8579695102f38ff034092",
    full_ref: "#Reference<0.0.575235.90977385.2484928515.120170>",
    full_name: "1110df0436fd62b85bb8579695102f38ff034092-m1440.webp"
  },
  %{
    base: "1110df0436fd62b85bb8579695102f38ff034092",
    pred_ref: "#Reference<0.0.575235.90977385.2484928515.120244>",
    ml_name: "1110df0436fd62b85bb8579695102f38ff034092-m512.webp"
  },
  %{
    base: "1110df0436fd62b85bb8579695102f38ff034092",
    thumb_ref: "#Reference<0.0.575235.90977385.2484928515.120256>",
    thumb_name: "1110df0436fd62b85bb8579695102f38ff034092-m200.webp"
  }
]

to:

[
  %{
    base: "1110df0436fd62b85bb8579695102f38ff034092",
    pred_ref: "#Reference<0.0.575235.90977385.2484928515.120244>",
    thumb_ref: "#Reference<0.0.575235.90977385.2484928515.120256>",
    full_ref: "#Reference<0.0.575235.90977385.2484928515.120170>",
    ml_name: "1110df0436fd62b85bb8579695102f38ff034092-m512.webp",
    thumb_name: "1110df0436fd62b85bb8579695102f38ff034092-m200.webp",
    full_name: "1110df0436fd62b85bb8579695102f38ff034092-m1440.webp"
  },
  %{
    base: "dff3a13e58c2fcb2d1382f8f016e035405bad359",
    pred_ref: "#Reference<0.0.575235.90977385.2484928518.78487>",
    thumb_ref: "#Reference<0.0.575235.90977385.2484928518.78510>",
    full_ref: "#Reference<0.0.575235.90977385.2484928518.78414>",
    ml_name: "dff3a13e58c2fcb2d1382f8f016e035405bad359-m512.webp",
    thumb_name: "dff3a13e58c2fcb2d1382f8f016e035405bad359-m200.webp",
    full_name: "dff3a13e58c2fcb2d1382f8f016e035405bad359-m1440.webp"
  }
]

One can do:

def merge_maps(list, key) do
    have_key = fn map, curr, key -> Map.get(map, key) == Map.get(curr, key) end

    find_curr_in_acc = fn acc, curr, key ->
      Enum.find(acc, fn map -> have_key.(map, curr, key) end)
    end

    list
    |> Enum.reduce([], fn curr, acc ->
      case find_curr_in_acc.(acc, curr, key) do
        nil ->
          [curr | acc]

        exists ->
          [Map.merge(exists, curr) | Enum.filter(acc, &(&1 != exists))]
     end
 end)

ndrean avatar Oct 25 '23 17:10 ndrean