我正在学习Elixir,发现自己必须将多个列表连在一起,我有一个开头,中间和结尾.简化示例:
a = [1,2] b = [3,4] c = [5,6] a ++ b ++ c > [1, 2, 3, 4, 5, 6]
我在流中做了数千次,想要成为Elixirific.
我写了一个处理这个问题的函数,可能有些东西可以帮到我,但是我没有看到它.我应该使用内置的Elixir功能吗?
def append(front, back) when is_list(front) when is_list(back) do front |> Enum.reverse |> Enum.reduce(back, &([&1 | &2])) end
或者我应该这样做,随着时间的推移对我来说会更自然吗?
[1, 2] |> Enum.reverse |> Enum.reduce([3, 4], &([&1 | &2])) |> Enum.reverse |> Enum.reduce([5, 6], &([&1 | &2]))
我将这些部件称为一起的顺序是否重要?
Way 1: [1, 2] |> append([3, 4]) |> append([5, 6]) ... Way 2: end = append([3, 4], [5, 6]) append([1, 2], end)
中间列表是否会在两种情况下重复使用,因为它们都附加了标题指针?
对此的任何帮助都会很棒,欢呼.
无论您使用什么方法,最终都会克隆至少除最后一个列表之外的所有列表,因为您无法在不克隆链接的情况下附加到链接列表.因此,如果您知道要连接列表(即您不能修改代码以接受嵌套列表[a, b, c]
),我建议a ++ b ++ c
自从++
在Erlang的C代码中实现,它应该尽可能快,并且肯定比手动连接Enum.reverse/1
和Enum.reduce/3
.
这里有一个小小的微基准比较a ++ b ++ c
VS a |> append(b) |> append(c)
:
defmodule BasicBench do use Benchfella bench "++", [a: gen(), b: gen(), c: gen()] do a ++ b ++ c end bench "append", [a: gen(), b: gen(), c: gen()] do a |> append(b) |> append(c) end def append(front, back) when is_list(front) when is_list(back) do front |> Enum.reverse |> Enum.reduce(back, &([&1 | &2])) end def gen, do: Enum.to_list(1..1000) end
和输出:
benchma iterations average time ++ 100000 10.22 µs/op append 20000 75.79 µs/op