collectivelysuperior

collectivelysuperior

Accessing list element with put_in for lists of structs

Let’s say there is a list of structs as a field of a parent struct. Due to the nested nature of the list of maps in the struct, I have been using put_in to insert a new value into the child struct. However, I find myself having to get the index of the child struct in the list and then using that index to access the child struct in the nested list. Is there a better way of doing this? I have searched online and haven’t found much useful info.

In my use case (shown below), the parent struct is a game and the list contains player structs. I am trying to update the player in the list to be the opposite of their current mute boolean.

defmodule Game do
  defstruct id: nil, name: nil, password: nil, connected_users: [], messages: []
end

defmodule Player do
  defstruct id: nil, muted?: false
end

def mute(%{connected_players: connected_players} = game, player) do
    index = Enum.find(connected_players, &(player == &1.id)
    game
    |> put_in([:connected_players, Access.at!(index), :muted?], not player.muted?)
  end

Marked As Solved

thiagomajesk

thiagomajesk

Hi @collectivelysuperior, welcome to the forum!

I think you can do try something like this:

def mute(%{connected_players: connected_players} = game, %{id: player_id}) do
  players = Enum.map(connected_players, fn 
    {id: ^player_id, muted?: false} = player -> %{player | muted?: true}
    player -> player
end

%{game | connected_players: players}

Also Liked

qhwa

qhwa

I think finding a player by id is quite frequent. For example, when a player joins the game, you also want to make sure you won’t add him/her twice if already in the room.

So I often end up with having the connected_players list as a map, whose keys are ids. Would that be easier for you?

%Game{connected_players: %{"foo" => %Player{id: "foo", ...}}}
shd42

shd42

If you want to keep using put_in, you could do it like this (haven’t tested it, but should be fine):

def mute(%Game{} = game, %Player{id: id} = player) do
  put_in(game, [
     Access.key(:connected_players), 
     Access.filter(&match?(%{id: ^id}, &1)), 
     Access.key(:muted?)
  ], not player.muted?)
end

Where Next?

Popular in Questions Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
logicmason
Hi there, I'm working through my first release with elixir/phoenix. I've built a release with distillery and found that it crashes when I...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
mathew4509
I have a list say x = ["23gh", "56kh", "97mh"] I would like to pass each element to Val in each iteration. Say, in iteration 1 -------...
New
chewm
Hi guys, nice to meet you to the whole forum, I’m new here, I’m trying to configure visual studio code for elixir, right now the intellis...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

We're in Beta

About us Mission Statement