[Proposal] Map.take_in/2

47 views
Skip to first unread message

Samuel Manzanera

unread,
Sep 2, 2020, 8:30:36 AM9/2/20
to elixir-lang-core

Hello everybody,

I propose the support of Map.take_in/2 to extract values using nested keys (recursively).

I think it may be useful when you only want a part of the map -- mostly when its deep nested map (i.e KV stores, DB engines, etc..) to reduce memory footprint with copy and message passing.

Example:


iex> Map.take_in(%{a: "hello", b: %{c: "hi", d: "hola"}}, [:a, b: [:d]])

%{a: "hello", b: %{d: "hola"}}

As discussed in the #1029 the feature should be extended to Access  for both Map and Keyword implementation.

To analyse the efficiency regarding pattern matching.

But it's a way to resolve the duplication from pattern matching as in this example.

iex> %{a: a, b: %{d: d}} = %{a: "hello", b: %{c: "hi", d: "hola"}}
iex> %{a: a, b: %{d: d}}
%{a: "hello", b: %{d: "hola"}}


Thanks :)

Samuel Manzanera

unread,
Sep 2, 2020, 8:34:45 AM9/2/20
to elixir-lang-core
Another advantage it is the support of dynamic key pattern matching.
If you are supporting function which accept paramete as the keys to filter the map, so it can be dynamically filtered out.

Example

def get_data(fields) do
   get_map_from_state_or_db()
   |> Map.take_in(fields) # or take_in (with Access implementation)

end

Fernando Tapia Rico

unread,
Sep 2, 2020, 8:50:27 AM9/2/20
to elixir-lang-core
I think the syntax might be ambiguous in some edge gases because the keys on a map can be anything. For example:

iex(1)> map = %{:a => "hello", {:b, [:d]} => 1, :b => %{d: 3}}
%{:a => "hello", :b => %{d: 3}, {:b, [:d]} => 1}
iex(2)> Map.take(map, [:a, b: [:d]])
%{:a => "hello", {:b, [:d]} => 1}

Reply all
Reply to author
Forward
0 new messages