Erlang 替换嵌套映射中的键
如何在不知道路径(或替换与模式匹配的键)的情况下,用另一个键替换嵌套贴图中的所有键,例如:Erlang 替换嵌套映射中的键,erlang,maps,Erlang,Maps,如何在不知道路径(或替换与模式匹配的键)的情况下,用另一个键替换嵌套贴图中的所有键,例如: Map = #{foo => #{bar => 1, foo => #{bar => 2}}}. Map2 = maps:keyreplace(bar, foo, Map). >>> #{foo => #{foo => 1, foo => #{foo => 2}}} 最有效的方法是什么? 在平面地图中替换关键点似乎非常简单: keyrep
Map = #{foo => #{bar => 1, foo => #{bar => 2}}}.
Map2 = maps:keyreplace(bar, foo, Map).
>>> #{foo => #{foo => 1, foo => #{foo => 2}}}
最有效的方法是什么?在平面地图中替换关键点似乎非常简单:
keyreplace(K1, K2, M) when is_map(M) ->
case maps:take(K1, M) of
{V, M2} ->
maps:put(K2, V, M2);
error -> M
end.
或者像这样,也许:
keymap(F, Map) ->
maps:fold(fun(K, V, Acc) ->
maps:put(F(K), V, Acc)
end, #{}, Map).
Map = #{foo => 1, bar => 2}.
Fun = fun(K) -> atom_to_list(K) end.
Map2 = keymap(Fun, Map).
>>> #{"bar" => 2,"foo" => 1}
我编写了递归函数,您可以使用它来实现您的目标,它需要3个参数: Is_matched-检查键是否与模式匹配的函数 Convert-根据需要转换密钥的函数 映射-映射到进程
replace_keys(Is_matched, Convert, Map) when is_map(Map) ->
maps:fold(fun (K, V, AccIn) ->
NewKey =
case Is_matched(K) of
true -> Convert(K);
false -> K
end,
maps:put(NewKey, replace_keys(Is_matched, Convert, V), AccIn)
end, #{}, Map);
replace_keys(_, _, Term) -> Term.
例如:
1> Map = #{a => "1", <<"b">> => #{c => "2", <<"d">> => 3}}.
#{a => "1",<<"b">> => #{c => "2",<<"d">> => 3}}
2> Is_matched = fun(Term) -> is_atom(Term) end.
#Fun<erl_eval.6.99386804>
3> Convert = fun(Term) -> atom_to_list(Term) end.
#Fun<erl_eval.6.99386804>
4> keyreplace:replace_keys(Is_matched, Convert, Map).
#{"a" => "1",<<"b">> => #{"c" => "2",<<"d">> => 3}}
1>Map={a=>1',=>c=>2',=>3}。
#{a=>“1”、=>{c=>“2”、=>3}
2> Is_matched=fun(Term)->Is_atom(Term)end。
#乐趣
3> Convert=fun(术语)->atom\u to\u列表(术语)结束。
#乐趣
4> 键替换:替换键(匹配、转换、映射)。
#{“a”=>“1”、=>{“c”=>“2”、=>3}
这可以通过对贴图:折叠进行一些修改来完成:
如果第三个参数不是映射,则按原样返回它
折叠时:
使用value字段递归调用函数以获取新值
如果键与K1匹配,则将新值放入K2
您的示例输出不正确-它有两个foo
键的值。我在下面的测试中修改了它
keyreplace(K1, K2, Map) when is_map(Map) ->
maps:fold(fun(K, V, Acc) ->
Key = if K == K1 -> K2; true -> K end,
Value = keyreplace(K1, K2, V),
maps:put(Key, Value, Acc)
end, #{}, Map);
keyreplace(_K1, _K2, Term) -> Term.
1> c(a).
{ok,a}
2> Map = #{foo => #{bar => 1, baz => #{bar => 2}}}.
#{foo => #{bar => 1,baz => #{bar => 2}}}
3> a:keyreplace(bar, foo, Map).
#{foo => #{baz => #{foo => 2},foo => 1}}