NJY404
NJY404

Reputation: 358

Convert struct to list in elixir

I'm new to Elixir. Currently using a Pheonix framework. I need to convert structs to list so I can use them in the select field.

In my user_controller.ex I attempt to convert a struct to list, but the variable user_types_name is always empty.

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

While in form.html.eex. For additional information

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

Upvotes: 0

Views: 1288

Answers (3)

sbacarob
sbacarob

Reputation: 2212

In Elixir, for is a construct for comprehensions. Meaning that the result will be a list built with the result of the do clause for each element in the enumerables you use.

So, in your example, you are in fact building a list where each element is the concatenation of user_type_names (which every time is the empty list you assigned) with the current user.name.

What was suggested about assigning won't really work inside the for's do clause, because of the scoping rules. You will be reassigning it but the result will actually be the same, because it will still be the result of the match (=).

The solution is actually far simpler than what you're doing. It's enough to do:

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

Upvotes: 1

Andrei R
Andrei R

Reputation: 11

You should perhaps look at Enum.map

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

Enum.map returns a list by itself, so you might want do something like

user_type_names = Enum.map(Accounts.list_user_types()...)

and this should return a list.

Documentation is pretty well written : https://hexdocs.pm/elixir/Enum.html

Elixir forces you to think about what module ( Enum ) and what function ( map ) you are going to use. Think functional is the key to make things work

Upvotes: 1

Lionel Rowe
Lionel Rowe

Reputation: 5956

All data in Elixir is immutable. ++ is a concatenation operator, not a way to mutate a list by pushing an item onto it.

You'll need to use something like this:

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

Or, more concisely:

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

Upvotes: 2

Related Questions