Current section

Files

Jump to
maputils src maputils.erl
Raw

src/maputils.erl

%% Erlang maps utillity functions
%%
-module(maputils).
%% API
-export([make_hierarchy/2,
make_hierarchy/3,
deep_get/2,
deep_put/3,
flatten_hierarchi/1]).
%% API ------------------------------------------------------------------------
make_hierarchy(Order, Maps) ->
make_hierarchy(Order, Maps, dont_keep).
make_hierarchy([], Maps, _) ->
Maps;
make_hierarchy([Key|Order], Maps, Keep) ->
Map = split_on_key(Key, Maps, Keep),
F = fun(InnerKey, InnerMaps, Acc) ->
Acc#{InnerKey=>make_hierarchy(Order, InnerMaps, Keep)}
end,
maps:fold(F, #{}, Map).
deep_get([Key|Keys], Map) ->
case maps:find(Key, Map) of
{ok, InnerMap} when is_map(InnerMap) ->
deep_get(Keys, InnerMap);
{ok, Val} ->
Val;
error ->
{error, {key_not_found, Key}}
end;
deep_get([], Value) ->
Value.
deep_put([Key|Keys], Value, Map) ->
case maps:find(Key, Map) of
{ok, InnerMap} ->
Map#{Key := deep_put(Keys, Value, InnerMap)};
error ->
Map#{Key => deep_put(Keys, Value, #{})}
end;
deep_put([], Value, _) ->
Value.
%% TODO: Implement
flatten_hierarchi(Map) -> Map.
%% Internal -------------------------------------------------------------------
split_on_key(Key, Maps, Keep) ->
F = fun(#{Key:=Val} = Map, Acc) ->
case maps:find(Val, Acc) of
{ok, InnerMaps} when Keep == keep ->
Acc#{Val:=[Map|InnerMaps]};
{ok, InnerMaps} when Keep == dont_keep ->
Acc#{Val:=[maps:remove(Key, Map)|InnerMaps]};
error when Keep == keep ->
Acc#{Val=>[Map]};
error when Keep == dont_keep ->
Acc#{Val=>[maps:remove(Key, Map)]}
end;
(_, _) ->
exit({key_not_found, Key})
end,
lists:foldl(F, #{}, Maps).