灵丹妙药如何在不经过两次地图的情况下同时进行映射和减少

Pot*_*ato 2 functional-programming elixir

我有包含订单的地图列表

%{price, order_details}
Run Code Online (Sandbox Code Playgroud)

我想获得该订单中的 total_price,我还想返回使用该地图中每个元素的 order_details 构建的变更集数组。如果不使用一个reduce 和一个map,我无法找到一种方法,但这是列表中的两次访问。这是函数式编程的一个好习惯吗?

Dog*_*ert 5

我假设数据如下所示:

list = [
  %{price: 1, order_details: "foo"},
  %{price: 2, order_details: "bar"},
  %{price: 3, order_details: "baz"},
]
Run Code Online (Sandbox Code Playgroud)

您仍然可以使用reducesum 和 list 元组作为累加器。

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

输出:

{6, ["baz", "bar", "foo"]}
Run Code Online (Sandbox Code Playgroud)


Ale*_*kin 5

@Dogbert 的回答也完全有效,在 Elixir ( Enum.map_reduce/3) 中有一个用于执行 map-reduce 的内置函数:

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}
Run Code Online (Sandbox Code Playgroud)