Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to update a list of structs

Tags:

elixir

Let's say that I have a list of structs, with an id as one of its keys:

users = [
  %User{id: 1, attempts: 5},
  %User{id: 2, attempts: 12},
  %User{id: 3, attempts: 2}
]

What would the best way (the most elixir way) to update the number of attempts to 99 of the user with id == 2 to get a new users list:

updated_users = [
  %User{id: 1, attempts: 5},
  %User{id: 2, attempts: 99},
  %User{id: 3, attempts: 2}
]

Thanks for helping!

like image 536
Iago Díaz Avatar asked Oct 20 '19 18:10

Iago Díaz


2 Answers

Enum.map(users, fn
  %User{id: 2} = user -> %User{user | attempts: 99}
  user -> user
end)

You can encapsulate it into some module and give it nice name :)

like image 177
Koziołek Avatar answered Nov 18 '22 18:11

Koziołek


Arguably, most elixirish approach would be to use Access behaviour and Kernel.put_in/3:

put_in users,
  [Access.filter(&match?(%User{id: 2}, &1)), 
   Access.key(:attempts)],
  99
#⇒ [
#  %User{attempts: 5, id: 1},
#  %User{attempts: 99, id: 2},
#  %User{attempts: 2, id: 3}
#]

This might be easily extended to update multiple elements by changing the filter function.

like image 5
Aleksei Matiushkin Avatar answered Nov 18 '22 18:11

Aleksei Matiushkin