将新元素添加到列表中

zer*_*ing 43 elixir

我试图将一个新元素添加到列表中,如下所示:

iex(8)> l = [3,5,7,7,8] ++ 3
[3, 5, 7, 7, 8 | 3]
iex(9)> l
[3, 5, 7, 7, 8 | 3]
Run Code Online (Sandbox Code Playgroud)

为什么我会像第五名一样获得第五名

8 | 3
Run Code Online (Sandbox Code Playgroud)

它的意思是什么?
如何在列表中添加新元素?

-------- 更新 --------
我尝试循环列表如下:

iex(2)> l = [1,2] ++ 3
[1, 2 | 3]
iex(3)> Enum.each(l, fn(x) -> IO.puts(x) end)
1
2
** (FunctionClauseError) no function clause matching in Enum."-each/2-lists^foreach/1-0-"/2
    (elixir) lib/enum.ex:604: Enum."-each/2-lists^foreach/1-0-"(#Function<6.54118792/1 in :erl_eval.expr/5>, 3)
    (elixir) lib/enum.ex:604: Enum.each/2
Run Code Online (Sandbox Code Playgroud)

由于数字2的指针不是指向列表而是指向值3,我如何循环列表?

Chi*_*ian 48

只需按照Elixir文档将一个元素添加到列表中(并记住性能=)):

iex> list = [1, 2, 3]
iex> [0 | list]   # fast
[0, 1, 2, 3]
iex> list ++ [4]  # slow
[1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

https://hexdocs.pm/elixir/List.html

  • 因为Elixir/Erlang中的列表是内部链接列表,所以在列表前面添加是一个快速操作,因为您不需要重新创建列表尾部的链接.因此,在列表末尾添加元素将要求链接列表从后到前再次重新创建所有链接. (10认同)
  • @EduardoPereira本质上是正确的,尽管链接没有重新创建,但它们被遍历了。遍历是一个读操作。在头部添加元素只需要添加的元素包含到列表其余部分(尾部)的链接。在末尾添加需要首先找到末尾,这意味着需要遍历整个列表,然后更新最后一个元素以包含指向所添加元素的链接。是遍历引入了性能影响,跟你说的相符。 (4认同)
  • 我不明白将元素附加到链表的计算成本如何,而前置却很便宜,直到我看到这个片段,它显示了列表下面的 cons 单元:`iex&gt; [1 | [2 | [3 | []]]] [1, 2, 3] ` (2认同)

Sal*_*ina 45

++运算符用于连接两个列表,那么为了添加新元素,您想要做的就是将它放在列表中.然后,我认为你应该将3添加到另一个列表中:

iex(2)> l = [3,5,7,7,8] ++ [3]

[3,5,7,7,8,3]

  • 来自[docs](http://elixir-lang.org/docs/master/elixir/List.html#content)的警告:"_由于他们的基于cons单元的表示,将元素添加到列表总是很快(恒定时间),随着列表增大(线性时间),追加变慢:_`iex> list = [1,2,3] iex> [0 | list] #fast [0,1,2,3] iex> list ++ [4] #blow [1,2,3,4]`" (11认同)
  • @SalvadorMedina不,在这种情况下是`8 | 3`表示不正确的列表.谷歌"Elixir不正确的名单",你会看到它是什么. (4认同)
  • Elixir中的列表是链接列表.A | B表示单元格A的指针指向B.在您的情况下,它表示列表的最后一个元素指向存储3的元素. (2认同)

Ono*_*cci 7

第一:[1,2 | 3]是不正确列表的表示法.

第二:要执行Enum.each,你要尝试使用不正确的列表,代码看起来像这样:

匹配正确/不正确的列表相应容易.所以长度函数len为正确的列表:

len([_ | T]) - > 1 + len(T); len([]) - > 0.我们明确匹配终止[].如果给出不正确的列表,则会产生错误.返回列表最后一个尾部的函数last_tail也可以处理不正确的列表:

last_tail([_ | T]) - > last_tail(T); last_tail(尾巴) - >尾巴.
%将匹配任何尾巴

当然,这是来自@rvirding的Erlang代码.转换为Elixir并翻译为您在示例中进行的打印,它看起来像这样:

iex(6)> defmodule T do
...(6)>   defp print([h|t]) do
...(6)>     IO.puts(h)
...(6)>     print(t)
...(6)>   end
...(6)>   defp print(t) do
...(6)>     IO.puts(t)
...(6)>   end
...(6)>   def print_improper_list(il), do: print(il)
...(6)> end
iex:6: warning: redefining module T
{:module, T,
 <<70, 79, 82, 49, 0, 0, 5, 136, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 161, 131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115, 95, 118, 49, 108, 0, 0, 0, 4, 104, 2, ...>>,
 {:print_improper_list, 1}}
iex(7)> T.print_improper_list([1,2,3|4])
1
2
3
4
:ok
Run Code Online (Sandbox Code Playgroud)

我把它作为练习让你弄清楚如何用Enum.each做到这一点.


han*_*na9 6

通过Enum.concat加入

例子:

iex> new_elem = 5
iex> Enum.concat([1, 2, 3], [new_elem])
[1, 2, 3, 5]
Run Code Online (Sandbox Code Playgroud)

  • 它在内部使用“Kernel.++/2”来连接列表。 (3认同)