VR_1
VR_1

Reputation: 153

How to merge two list with maps based on particular key

I have 2 list consisting of maps.

products =
[
  %{id: 7, name: "A", count: 1},
  %{id: 8, name: "B", count: 1},
  %{id: 9, name: "C", count: 0}
]

price=
[
  %{price: "$14.95", p_id: 8},
  %{price: "$10.00", p_id: 7},
  %{price: "$29.95", p_id: 10},
  %{price: "$1.00", p_id: 9}

]

I want to merge them in such a way that the matching id from price list should get merged with product list so that final list looks like

products=
[
  %{id: 7, name: "A", count: 1, price: "$10.00"},
  %{id: 8, name: "B", count: 1, price: "$14.95"},
  %{id: 9, name: "C", count: 0, price: "$1.00"}
]

How we can achieve this??

Upvotes: 0

Views: 246

Answers (1)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

The way you store data is not optimal. Linked lists are not a type of term one uses to store the data that is supposed to be looked up. Map %{id => details} would suit way better.

If you insist on using lists, it’s still doable. Assuming there are prices for all products existing, one might do

Enum.map(products, &Map.put(
  &1, :price, Enum.find(price, fn %{p_id: pid} -> pid == &1.id end).price))
#⇒ [
#    %{count: 1, id: 7, name: "A", price: "$10.00"},
#    %{count: 1, id: 8, name: "B", price: "$14.95"},
#    %{count: 0, id: 9, name: "C", price: "$1.00"}
#  ]

Here we basically map the input to itself, extending each map with what we looked up in the prices list. If the price might be absent, more careful handling of updating must take place.

Upvotes: 1

Related Questions