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