如何在elixir中通过索引获取列表元素

Pas*_*zyk 30 arrays list elixir

{status, body} = File.read("/etc/hosts")
if status == :ok do
    hosts = String.split body, "\n"
    hosts = Enum.map(hosts, fn(host) -> line_to_host(host) end)
else
    IO.puts "error reading: /etc/hosts"
end
Run Code Online (Sandbox Code Playgroud)

我有以下elixir函数,其中我读取/ etc/hosts文件并尝试使用逐行拆分String.split.

然后我映射主机的行列表并为每个主机调用line_to_host(host).line_to_host方法拆分行" ",然后我想设置fromto变量:

def line_to_host(line) do
    data = String.split line, " "
    from = elem(data, 0) // doesn't work
    to = elem(data, 1) // doesn't work either
    %Host{from: from, to: to}
end
Run Code Online (Sandbox Code Playgroud)

我查看了stackoverflow,elixir文档,并搜索了如何在特定索引处获取列表元素.我知道有,head/tail但必须有一个更好的方法来获取列表元素.

elem(list, index)完全符合我的需要,但遗憾的是它无法使用String.split.

如何在elixir中按ID获取列表/元组元素

Pat*_*ity 31

您可以使用模式匹配:

[from, to] = String.split line, " "
Run Code Online (Sandbox Code Playgroud)

也许你想添加parts: 2选项,以确保只有两个部分,以防行中有多个空格:

[from, to] = String.split line, " ", parts: 2
Run Code Online (Sandbox Code Playgroud)

还有Enum.at/2,这在这里工作得很好但是是单一的.问题Enum.at在于,由于Elixir中的列表实现,它需要遍历整个列表直到请求的索引,因此对于大型列表来说效率非常低.


编辑:这是请求的示例Enum.at,但在这种情况下我不会使用它

parts = String.split line, " "
from = Enum.at(parts, 0)
to = Enum.at(parts, 1)
Run Code Online (Sandbox Code Playgroud)

  • @WM你可以做`[head | tail].= list`(如果你需要第一个元素,head,以及):`tail = tl(list)`(如果你不需要头部)来获取列表的尾部,那么只需要映射那. (2认同)