将结构转换为 elixir 中的列表

Convert struct to list in elixir

我是 Elixir 的新手。目前使用 Pheonix 框架。我需要将结构转换为列表,以便我可以在 select 字段中使用它们。

在我的 user_controller.ex 中,我尝试将结构转换为列表,但变量 user_types_name 始终为空。

user_type_names = []
for user <- Accounts.list_user_types() do
     user_type_names ++ [user.name]
end

form.html.eex 期间。更多信息

<%= inputs_for f, :user_type, fn cf -> %>
    <%= label cf, :user_type %>
    <%= select cf, :user_type, @user_type_names %>
    <%= error_tag cf, :user_type %>
<% end %>

Elixir 中的所有数据都是不可变的。 ++ 是一个串联运算符,不是通过将项目推入列表来改变列表的方法。

你需要使用这样的东西:

user_type_names = Accounts.list_user_types()
  |> Enum.map(fn(user) -> user.name end)

或者,更简洁地说:

user_type_names = Accounts.list_user_types()
  |> Enum.map(&(&1.name))

你或许应该看看 Enum.map

Enum.map(1..3, fn x -> x * 2 end)
[2, 4, 6]

Enum.map return 本身就是一个列表,所以您可能想做类似

的事情
user_type_names = Enum.map(Accounts.list_user_types()...)

这应该 return 一个列表。

文档写得很好:https://hexdocs.pm/elixir/Enum.html

Elixir 迫使您考虑要使用的模块 ( Enum ) 和 function ( map )。认为功能性是使事情正常进行的关键

在 Elixir 中,for 是理解式的构造。这意味着结果将是一个列表,该列表由您使用的枚举中每个元素的 do 子句的结果构建。

因此,在您的示例中,您实际上是在构建一个列表,其中每个元素都是 user_type_names(每次都是您分配的空列表)与当前 user.name 的串联。

由于范围规则的原因,关于分配的建议在 fordo 子句中不会真正起作用。您将重新分配它,但结果实际上是相同的,因为它仍然是匹配的结果 (=)。

解决方案实际上比您正在做的要简单得多。够做:

user_type_names = for user <- Accounts.list_user_types(), do: user.name