defmodule Runbox.Utils.Map do @moduledoc """ A set of utility functions for Maps. """ @doc """ Follows the `path` in the (deep) map, defaulting to `default` if some of the objects on the path is missing. ## Example iex> object = %{"some" => %{"deep" => %{"object" => "data"}}} ...> Runbox.Utils.Map.get_path(object, ["some", "deep", "object"]) "data" iex> Runbox.Utils.Map.get_path(object, ["non-existent"], "default") "default" """ @spec get_path(map(), [binary() | atom()], any()) :: any() def get_path(map, path, default \\ nil) def get_path(map, [_ | _], default) when not is_map(map), do: default def get_path(map, [el], default) do Map.get(map, el, default) end def get_path(obj, [], default) do obj || default end def get_path(map, [el | rest], default) do get_path(Map.get(map, el, %{}), rest, default) end end