elixir

Elixir: best practice to extract data from nested structs


In Elixir we can get data from nested data structures using

data = %{field: %{other_field: 1}}
data[:field][:other_field]

If it contains lists it also can be done using

data = %{field: %{other_field: [1]}}
get_in data, [:field, :other_field, Access.at(0)]

But how to get that data given that data.field.other_field is a structure? Both of the above would fail because structs don't implement Access.fetch/2.

data = %{field: %{other_field: %Struct{a: 1}}}

So what's the right way to access nested structs data other than pattern matching?


Solution

  • Use Access.key/2:

    key(key, default \\ nil)

    Accesses the given key in a map/struct.

    Uses the default value if the key does not exist or if the value being accessed is nil.

    iex(1)> defmodule Struct do
    ...(1)>   defstruct [:a]
    ...(1)> end
    iex(2)> data = %{field: %{other_field: %Struct{a: 1}}}
    %{field: %{other_field: %Struct{a: 1}}}
    iex(3)> get_in data, [:field, :other_field, Access.key(:a)]
    1
    iex(4)> get_in data, [:field, :other_field, Access.key(:b, :default)]
    :default