Kernel.get_in
get_in
, go back to Kernel module for more information.
Specs
Gets a value from a nested structure.
Uses the Access
module to traverse the structures
according to the given keys
, unless the key
is a
function, which is detailed in a later section.
Examples
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}}
iex> get_in(users, ["john", :age])
27
In case any of the keys returns nil
, nil
will be returned:
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}}
iex> get_in(users, ["unknown", :age])
nil
Note that get_in
exists mostly for convenience and parity with
functionality found in put_in
and update_in
. Given Elixir
provides pattern matching, it can often be more expressive for
deep data traversal, for example:
case users do
%{"unknown" => %{age: age}} -> age
_ -> default_value
end
Functions as keys
If a key is a function, the function will be invoked passing three arguments:
- the operation (
:get
) - the data to be accessed
- a function to be invoked next
This means get_in/2
can be extended to provide custom lookups.
In the example below, we use a function to get all the maps inside
a list:
iex> users = [%{name: "john", age: 27}, %{name: "meg", age: 23}]
iex> all = fn :get, data, next -> Enum.map(data, next) end
iex> get_in(users, [all, :age])
[27, 23]
If the previous value before invoking the function is nil
,
the function will receive nil
as a value and must handle it
accordingly.
The Access
module ships with many convenience accessor functions,
like the all
anonymous function defined above. See Access.all/0
,
Access.key/2
, and others as examples.
Working with structs
By default, structs do not implement the Access
behaviour required
by this function. Therefore, you can't do this:
get_in(some_struct, [:some_key, :nested_key])
The good news is that structs have predefined shape. Therefore, you can write instead:
some_struct.some_key.nested_key
If, by any chance, some_key
can return nil, you can always
fallback to pattern matching to provide nested struct handling:
case some_struct do
%{some_key: %{nested_key: value}} -> value
%{} -> nil
end