Elixir:将列表列表转换为一个列表
Elixir: transforming list of lists into one list
假设我们有以下列表:
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
如何将其转换为一个列表,其中包含相应位置上每个元素的总和,以便最终结果为
[5, 10, 15, 20]
?
不太可能有更简洁的变体可用,但可以避免多次迭代列表并使用递归一次完成所有操作(不涉及元组和转换)。
transpose = fn
[[x | xs] | xss], fun ->
[[x | Enum.map(xss, &hd/1)] | fun.([xs | Enum.map(xss, &tl/1)], fun)]
[[] | xss], fun -> fun.(xss, fun)
[], _ -> []
end
#⇒ #Function<43.97283095/2 in :erl_eval.expr/5>
transpose.(lists, transpose)
#⇒ [[1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3], [4, 4, 4, 4, 4]]
lists |> transpose.(transpose) |> Enum.map(&Enum.sum/1)
#⇒ [5, 10, 15, 20]
或者,甚至更简单,避免中间转置:
sum = fn
[[] | _], _ -> []
xs, fun ->
[(xs |> Enum.map(&hd/1) |> Enum.sum()) |
fun.(Enum.map(xs, &tl/1), fun)]
end
sum.(lists, sum)
#⇒ [5, 10, 15, 20]
假设我们有以下列表:
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
如何将其转换为一个列表,其中包含相应位置上每个元素的总和,以便最终结果为
[5, 10, 15, 20]
?
不太可能有更简洁的变体可用,但可以避免多次迭代列表并使用递归一次完成所有操作(不涉及元组和转换)。
transpose = fn
[[x | xs] | xss], fun ->
[[x | Enum.map(xss, &hd/1)] | fun.([xs | Enum.map(xss, &tl/1)], fun)]
[[] | xss], fun -> fun.(xss, fun)
[], _ -> []
end
#⇒ #Function<43.97283095/2 in :erl_eval.expr/5>
transpose.(lists, transpose)
#⇒ [[1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3], [4, 4, 4, 4, 4]]
lists |> transpose.(transpose) |> Enum.map(&Enum.sum/1)
#⇒ [5, 10, 15, 20]
或者,甚至更简单,避免中间转置:
sum = fn
[[] | _], _ -> []
xs, fun ->
[(xs |> Enum.map(&hd/1) |> Enum.sum()) |
fun.(Enum.map(xs, &tl/1), fun)]
end
sum.(lists, sum)
#⇒ [5, 10, 15, 20]