Please do submit a pull request. It should be similar to "all/0" except it
expects a map instead (and then traverses only values). Thank you!


*José Valimhttps://dashbit.co/ <https://dashbit.co/>*


On Tue, Mar 18, 2025 at 3:03 PM David Pavlík <d.pa...@gmail.com> wrote:

> Hi!
>
> I've recently discovered that get_and_update_in/3 and friends can access
> multiple items at once via Access.all/0, Access.filter/1, and similar.
> It's a game changer for accessing deeply nested structures.
>
> However, there is no function in the standard library for accessing
> multiple items of a map (similarly to items of a list). For maps where keys
> are something item IDs and not predefined atoms, I think such accessors
> would be very useful. In our codebase, for example, we often manipulate
> deeply nested structures that include such maps and want to access all
> values in such maps (e.g., when migrating data).
>
> It's easy to write an accessor that accesses all values in a map (and
> similarly for keys or both keys and values):
>
> @doc """
> Returns a function that accesses all values in a map.
>
> The returned function is typically passed as an accessor to
> `Kernel.get_in/2`,
> `Kernel.get_and_update_in/3`, and friends.
>
> ## Examples
>
>     iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}}
>     iex> get_in(users, [AccessUtils.values(), :age])
>     [27, 23]
>     iex> update_in(users, [AccessUtils.values(), :age], fn age -> age + 1
> end)
>     %{"john" => %{age: 28}, "meg" => %{age: 24}}
>     iex> put_in(users, [AccessUtils.values(), :phone], nil)
>     %{"john" => %{age: 27, phone: nil}, "meg" => %{age: 23, phone: nil}}
>
> """
> @spec values() :: Access.access_fun(data :: map(), current_value :: list())
> def values do
>   fn
>     :get, %{} = data, next ->
>       Enum.map(data, fn {_key, value} -> next.(value) end)
>
>     :get_and_update, %{} = data, next ->
>       {reverse_gets, updated_data} =
>         Enum.reduce(data, {[], %{}}, fn {key, value}, {gets, data_acc} ->
>           case next.(value) do
>             {get, update} -> {[get | gets], Map.put(data_acc, key, update)}
>             :pop -> {[value | gets], data_acc}
>           end
>         end)
>
>       {Enum.reverse(reverse_gets), updated_data}
>   end
> end
>
> Nevertheless, I think it might be useful to include it in the Access
> module of the standard library. What do you think?
>
> Note that something similar has already been discussed on Elixir Forum
> <https://elixirforum.com/t/how-to-use-update-in-on-multiple-map-keys-at-once-re-access-all/63963>
> .
>
> Best regards,
> David
>
> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elixir-lang-core+unsubscr...@googlegroups.com.
> To view this discussion visit
> https://groups.google.com/d/msgid/elixir-lang-core/847b6461-aaf4-4d2c-abbd-6b2ddee73b21n%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/847b6461-aaf4-4d2c-abbd-6b2ddee73b21n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4LYkUMdADcdA0q_M-eHOiizzMHYT%3D6e94qUqbTyHAf_Pw%40mail.gmail.com.

Reply via email to