Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

elixir how to map and reduce at the same time without going through the map twice

I have list of map of orders that contain

%{price, order_details}

I wanted to get the total_price in that orders and I also want to return and array of changeset that was build using the order_details of each element in that map. I can't find a way to do it without using one reduce and one map but that is two trip in to the list. it is that a good practice in functional programming?

like image 633
Potato Avatar asked Nov 27 '25 04:11

Potato


2 Answers

I'm assuming the data looks like this:

list = [
  %{price: 1, order_details: "foo"},
  %{price: 2, order_details: "bar"},
  %{price: 3, order_details: "baz"},
]

You can still use reduce with a tuple of sum and list as the accumulator.

list
|> Enum.reduce({0, []}, fn x, {sum, list} ->
  {sum + x.price, [x.order_details | list]}
end)
|> IO.inspect

Output:

{6, ["baz", "bar", "foo"]}
like image 147
Dogbert Avatar answered Nov 28 '25 17:11

Dogbert


Also answer by @Dogbert is perfectly valid, there is a built-in for doing map-reduce in Elixir (Enum.map_reduce/3):

list = [
  %{price: 1, order_details: "foo"},
  %{price: 2, order_details: "bar"},
  %{price: 3, order_details: "baz"},
]
Enum.map_reduce(list, 0, fn(%{order_details: od, price: p}, acc) ->
  {od, acc + p} # `od` is a mapper, `acc + p` is a reducer
end)
#⇒ {["foo", "bar", "baz"], 6}
like image 43
Aleksei Matiushkin Avatar answered Nov 28 '25 17:11

Aleksei Matiushkin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!