elixir如何在不经过地图两次的情况下同时映射和缩小

时间:2018-01-06 17:55:14

标签: functional-programming elixir

我有包含

的订单地图列表
%{price, order_details}

我希望获得该订单中的total_price,并且我还想返回使用该映射中每个元素的order_details构建的变更集数组。 我无法在不使用一张reduce和一张地图的情况下找到一种方法,但这是两次进入列表的行程。这是函数式编程的一个很好的实践吗?

2 个答案:

答案 0 :(得分:4)

我假设数据如下:

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

您仍然可以将reduce与sum和list的元组一起用作累加器。

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

输出:

{6, ["baz", "bar", "foo"]}

答案 1 :(得分:4)

@Dogbert的答案也完全有效,有一个内置的用于在Elixir中进行map-reduce(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}