View Source Toolbox.Utils.Map (toolbox v5.4.10)
A set of utility functions for maps.
Summary
Functions
Creates deep map with value
on key represented by path
. If path
is empty,
it returns given value
.
Deeply updates left
map by right
map.
Removes key represented as path (list of keys) deeply in map if it exists.
Converts map from flat to nested map.
Follows the path
in the (deep) map, defaulting to default
if some of the
objects on the path is missing.
Extracts all (json-like) paths in the map.
Subtracts map from another map, the leaf-paths from the second map are removed from the first.
Converts regular nested map to flat map.
Functions
Creates deep map with value
on key represented by path
. If path
is empty,
it returns given value
.
Examples
iex> Toolbox.Utils.Map.deep_create([], :some_value)
:some_value
iex> Toolbox.Utils.Map.deep_create(["a", :b], :other_value)
%{"a" => %{:b => :other_value}}
Deeply updates left
map by right
map.
Existing keys from left
map not contained in right
map are unchanged. New keys from right
map are added. If the key is present in both maps and both values are maps, maps are deeply
merges. If the key is present in both maps and value of one of them is not a map, value of key
in left
map is replaced by value in right
map.
Example
iex> Toolbox.Utils.Map.deep_merge(%{a: 1}, %{b: 2})
%{a: 1, b: 2}
iex> Toolbox.Utils.Map.deep_merge(%{a: %{b: 1}}, %{a: %{c: 3}})
%{a: %{b: 1, c: 3}}
iex> Toolbox.Utils.Map.deep_merge(%{a: %{b: %{c: 1}}}, %{a: %{b: %{d: 2}}})
%{a: %{b: %{c: 1, d: 2}}}
iex> Toolbox.Utils.Map.deep_merge(%{a: 1}, %{a: %{b: 2}})
%{a: %{b: 2}}
iex> Toolbox.Utils.Map.deep_merge(%{a: %{b: 1}}, %{a: 2})
%{a: 2}
iex> Toolbox.Utils.Map.deep_merge(%{a: 1}, %{a: 2})
%{a: 2}
Removes key represented as path (list of keys) deeply in map if it exists.
Example
iex> Toolbox.Utils.Map.deep_remove(%{a: 1, b: 2}, [])
%{a: 1, b: 2}
iex> Toolbox.Utils.Map.deep_remove(%{a: 1, b: 2}, [:a])
%{b: 2}
iex> Toolbox.Utils.Map.deep_remove(%{a: 1, b: 2}, [:a, :aa])
%{a: 1, b: 2}
iex> Toolbox.Utils.Map.deep_remove(%{a: %{aa: 1, ab: 2}, b: 2}, [:a, :aa])
%{a: %{ab: 2}, b: 2}
iex> Toolbox.Utils.Map.deep_remove(%{a: %{aa: 1, ab: 2}, b: 2}, [:a, :aa, :aaa])
%{a: %{aa: 1, ab: 2}, b: 2}
Converts map from flat to nested map.
The input map must be flat with array keys, which represent the path to the respective values. The corresponding nested map is then constructed.
Also see to_flat_map/1
which performs the reverse operation.
Examples
iex> Toolbox.Utils.Map.from_flat_map(%{
...> ["contact", "name"] => "Jored",
...> ["contact", "address", "city"] => "Lrno",
...> ["active", "ui"] => true,
...> ["active", "backend"] => false
...> })
%{
"contact" => %{
"name" => "Jored",
"address" => %{
"city" => "Lrno"
}
},
"active" => %{
"ui" => true,
"backend" => false
}
}
iex> Toolbox.Utils.Map.from_flat_map(%{
...> [:very, :very, :very, :very, :very, :very, :deep] => "object",
...> [:very, :very, :very, :very, :very, :very, :nested] => "map"
...> })
%{
very: %{
very: %{
very: %{
very: %{
very: %{
very: %{
deep: "object",
nested: "map"
}
}
}
}
}
}
}
iex> Toolbox.Utils.Map.from_flat_map(%{})
%{}
iex> Toolbox.Utils.Map.from_flat_map(Toolbox.Utils.Map.to_flat_map(%{
...> "contact" => %{
...> "name" => "Jonas",
...> "address" => %{"city" => "Brnp"}},
...> "favorites" => %{
...> "food" => %{
...> 1 => ["cornflakes", "corn"],
...> 5 => ["pizza"],
...> 8 => ["pasta"]
...> }
...> }
...> }
...> ))
%{
"contact" => %{
"name" => "Jonas",
"address" => %{"city" => "Brnp"}},
"favorites" => %{
"food" => %{
1 => ["cornflakes", "corn"],
5 => ["pizza"],
8 => ["pasta"]
}
}
}
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"}}}
...> Toolbox.Utils.Map.get_path(object, ["some", "deep", "object"])
"data"
iex> Toolbox.Utils.Map.get_path(object, ["non-existent"], "default")
"default"
Extracts all (json-like) paths in the map.
Given any artitrarily nested map, the function returns all paths the map contains.
The output is not sorted in a predictable way.
Examples
iex> Toolbox.Utils.Map.json_paths(%{
...> "contact" => %{
...> "name" => "Trest",
...> "phone" => 605554171,
...> "address" => %{"city" => "Brno"}
...> },
...> "active" => false
...> }) |> Enum.sort()
[
["active"],
["contact", "address", "city"],
["contact", "name"],
["contact", "phone"],
]
iex> Toolbox.Utils.Map.json_paths(%{"a" => %{1 => %{%{"cool" => "stuff"} => %{atom: :work_too}}}})
[
["a", 1, %{"cool" => "stuff"}, :atom]
]
iex> Toolbox.Utils.Map.json_paths(%{})
[]
Subtracts map from another map, the leaf-paths from the second map are removed from the first.
Examples
iex> Toolbox.Utils.Map.subtract(%{a: 1, b: 2}, %{a: true})
%{b: 2}
iex> Toolbox.Utils.Map.subtract(%{a: 1}, %{a: %{b: %{c: true}}})
%{a: 1}
iex> Toolbox.Utils.Map.subtract(
...> %{a: %{b: %{c: "1"}, d: "2"}, e: "3"},
...> %{a: %{b: %{c: true}}, e: true}
...> )
%{a: %{b: %{}, d: "2"}}
iex> Toolbox.Utils.Map.subtract(
...> %{"a" => 1, "b" => %{"c" => true}},
...> %{"b" => %{"c" => true}}
...> )
%{"a" => 1, "b" => %{}}
iex> Toolbox.Utils.Map.subtract(%{a: 1, b: 2}, %{c: 2, d: 3})
%{a: 1, b: 2}
iex> Toolbox.Utils.Map.subtract(%{a: %{b: 1}}, %{a: true})
%{}
Converts regular nested map to flat map.
The input map can be any map - arbitrarily nested, the output is a flat map where keys are arrays representing the path to the respective value.
Also see from_flat_map/1
which performs the reverse operation.
Examples
iex> Toolbox.Utils.Map.to_flat_map(%{
...> "contact" => %{
...> "name" => "Kert",
...> "address" => %{"city" => "Krno"}
...> },
...> "status" => %{"ui" => %{"active" => true},
...> "backend" => %{"fluent" => false}}
...> })
%{
["contact", "name"] => "Kert",
["contact", "address", "city"] => "Krno",
["status", "ui", "active"] => true,
["status", "backend", "fluent"] => false
}
iex> Toolbox.Utils.Map.to_flat_map(%{good: %{1 => :nice}, very: %{deep: %{%{ish: :map} => :askey}}})
%{
[:good, 1] => :nice,
[:very, :deep, %{ish: :map}] => :askey
}
iex> Toolbox.Utils.Map.to_flat_map(%{"regular" => "map"})
%{
["regular"] => "map"
}
iex> Toolbox.Utils.Map.to_flat_map(%{})
%{}