Search code examples
functional-programmingelixir

How to map list using value from another list 1 by 1 in Elixir?


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.


Solution

  • 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)