Reputation: 886
Suppose I have a Player Struct inside list
[
%Player{name: "John", role: "nil"},
%Player{name: "Sansa", role: "nil"},
%Player{name: "Barry", role: "nil"},
%Player{name: "Edward", role: "nil"}
]
and I have a list of roles:
Enum.shuffle([:werewolf, :farmer, :farmer, :farmer])
What function to use || How do I map it one by one into my expected result:
[
%Player{name: "John", role: ":farmer"},
%Player{name: "Sansa", role: ":farmer"},
%Player{name: "Barry", role: ":werewolf"},
%Player{name: "Edward", role: ":farmer"}
]
I tried mapping, but with OO background, all I think is matching the index, which is not efficient in Elixir.
Upvotes: 0
Views: 142
Reputation: 23091
You could take a different approach: make them all farmers, and randomly assign one as the warewolf:
defmodule Player do
defstruct name: nil, role: :farmer
def setup do
[werewolf | farmers] =
["John", "Sansa", "Barry", "Edward"]
|> Enum.map(fn name -> %Player{name: name} end)
|> Enum.shuffle()
[%Player{werewolf | role: :werewolf} | farmers]
end
end
This will return the players in a random order, though (and the werewolf will always be first).
Upvotes: 1
Reputation: 3159
In general, when you want to somehow work with two lists on the same size and do something element-wise, Enum.zip/2
or Enum.zip_with/3
are a common and efficient way to achieve it without relying on index access.
Your example can be solved by:
Enum.zip_with(players, roles, fn player, role -> Map.put(player, :role, role) end)
Upvotes: 3