What's the best way to access and retrieve data from deeply nested Maps and Lists?

This is an interesting problem. It won’t be possible to have a completely generic solution, but let us assume that you always get a list of maps the the following code would help:

defmodule NestedMaps do

  def nested_map() do
    %{"accessConfigs" =>
      [%{"kind" => "compute#accessConfig",
         "name" => "External NAT",
         "natIP" => "146.148.23.208",
         "type" => "ONE_TO_ONE_NAT"}
      ]
     }
  end

  def nested_map2() do
    %{"accessConfigs" =>
      [
        [%{"kind" => "compute#accessConfig",
         "name" => "External NAT",
         "natIP" => ["146.148.23.208","127.0.0.1"],
         "type" => "ONE_TO_ONE_NAT"}
        ],
        [{:config1,"c"}]
      ]
     }
  end

  def get_nested_map(nm) do
    %{"accessConfigs" => nestedmaplist} = nm
    nestedmaplist
  end

  def get_nested_map_from_list(nm, nestedlevel) when nestedlevel < 1 do
    nm
  end

  def get_nested_map_from_list(nm, nestedlevel) do
    get_nested_map_from_list(List.first(nm),nestedlevel-1)
  end

  def get_nested_map_value(nm, val) do
    Map.get nm,val
  end

end

A line like

NestedMaps.nested_map
    |> NestedMaps.get_nested_map 
    |> NestedMaps.get_nested_map_from_list(1) 
    |> NestedMaps.get_nested_map_value "natIP"

would return “146.148.23.208” from your original map list.

NestedMaps.nested_map2 
    |> NestedMaps.get_nested_map 
    |> NestedMaps.get_nested_map_from_list(2) 
    |> NestedMaps.get_nested_map_value "natIP"

would return [“146.148.23.208”, “127.0.0.1”] from the example in the code.

2 Likes