如何使用“|”将多个列表附加到现有列表?

How to use the "|" to append more than one list to an existing one?

我有这个:

<%= for x <- [
  "a1.css",
  "a2.css",
  | List.wrap(assigns[:my_css])
  ] do %>

我如何需要向其中添加一个 css 文件列表,而不必使用 ++

但这不会编译:

<%= for x <- [
  "a1.css",
  "a2.css",
  | List.wrap(assigns[:my_css])
  | ["my_custom1.css", "my_custom2.css"] # won't compile
  ] do %>

如何解决?

订单应保持原样。

简答:你不能,你必须改用 ++,所以:

l1 = [1,2,3]
l2 = [4,5,6]
[7, 8 | l1] ++ l2 # => [7, 8, 1, 2, 3, 4, 5, 6] 

更长的答案 - 当您使用 [|] 时,您是在将项目添加到列表中。这可以在不更改原始列表的情况下完成,方法是创建一个新列表,其中旧列表是一个尾部(这是一个 O(1) 操作)。但是当你想连接两个列表时,它不能通过这种简单的方式实现 - 为了保留两个原始列表(你必须这样做,因为 Elixir 数据是不可变的)Elixir 必须通过在每个项目之前添加来自一个列表到另一个列表,所以这是一个 O(n) 操作。因此,(我怀疑)有一个不同的操作员用于此目的。

| 运算符总是构建 [single_item | existing_list]

您始终可以构建多个列表:["a1" | ["a2" | another_list]] 并获得您正在寻找的结果单个列表 - 但您只能尝试找出哪些项目是列表。

从你的代码示例来看,你似乎在尝试解决两个问题:建立一个 CSS 文件名列表,然后在 for循环。

在 Elixir 中使用 Enum.map()Enum.reduce() 来做同样的事情是很常见的,没有 for 循环。 (在不知道您的实际最终目标的情况下很难说。)

至少,您可以简单地执行以下两个步骤:

  • 建立你关心的项目列表
  • 然后用 forEnum.map()
  • 遍历它们
# if everything was wrapped as a List already
css_files = Enum.concat([["a1.css"], List.wrap(assigns[:my_css]), ["b2.css", "b3.css"]])

# or, if it's not
css_files = List.flatten(["a1.css", ["c2.css", "c3.css"]])

# separately
for x <- css_files do
  # ...
end