假设我有一个单词列表,其中一个关键字,在这种情况下是"停止",划分完整的句子:
["Hello", "from", "Paris", "stop", "Weather", "is", "sunny", "stop", "Missing", "you", "stop"]
Run Code Online (Sandbox Code Playgroud)
我想变成:
[["Hello", "from", "Paris"], ["Weather", "is", "sunny"], ["Missing", "you"]]
Run Code Online (Sandbox Code Playgroud)
我知道我可以用String.split的字符串做到这一点,但理想情况下我想学习如何用基本的功能结构解决上述问题,比如[head | tail]等的递归,但我无法弄清楚在哪里去开始如何累积中间列表.
你可以使用chunk_by/2:
["Hello", "from", "Paris", "stop", "Weather", "is", "sunny", "stop", "Missing", "you", "stop"]
|> Enum.chunk_by(fn(x) -> x != "stop" end)
|> Enum.reject(fn(x) -> x == ["stop"] end)
Run Code Online (Sandbox Code Playgroud)
出于好奇,我想对这个问题的实现性能进行基准测试.基准测试是针对每个实现的100,000次调用,我运行了3次.如果有人有兴趣,以下是结果:
0.292903s | 0.316024s | 0.292106s | chunk_by
0.168113s | 0.152456s | 0.151854s | Main.main(@ Dogbert的回答)
0.167387s | 0.148059s | 0.143763s | chunk_on(@Martin Svalin的回答)
0.177080s | 0.180632s | 0.185636s | 分裂器(@ stephen_m的答案)
这是使用模式匹配的简单尾递归实现:
defmodule Main do
def split_on(list, on) do
list
|> Enum.reverse
|> do_split_on(on, [[]])
|> Enum.reject(fn list -> list == [] end)
end
def do_split_on([], _, acc), do: acc
def do_split_on([h | t], h, acc), do: do_split_on(t, h, [[] | acc])
def do_split_on([h | t], on, [h2 | t2]), do: do_split_on(t, on, [[h | h2] | t2])
def main do
["Hello", "from", "Paris", "stop", "Weather", "is", "sunny", "stop", "Missing", "you", "stop"]
|> split_on("stop")
|> IO.inspect
end
end
Main.main
Run Code Online (Sandbox Code Playgroud)
输出:
[["Hello", "from", "Paris"], ["Weather", "is", "sunny"], ["Missing", "you"]]
Run Code Online (Sandbox Code Playgroud)