erlang - 替换嵌套映射中的键

标签 erlang maps

如何在不知道路径的情况下用另一个键替换嵌套映射中的所有键(或替换匹配模式的键),例如:

Map = #{foo => #{bar => 1, foo => #{bar => 2}}}.
Map2 = maps:keyreplace(bar, foo, Map).
>>> #{foo => #{foo => 1, foo => #{foo => 2}}}

最有效的方法是什么?
替换平面 map 中的键似乎非常简单:

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 - 根据需要转换 key 的函数。

Map - 映射到进程。

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}}

关于erlang - 替换嵌套映射中的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47773575/

相关文章:

c++ - 通过 C++ 与 erlang 服务器通信(发送二进制文件)

javascript - Bing map 信息框

javascript - 如何在逻辑上划分为多个部分的 map 上显示标记(巨大的数字)?

maps - R 上的交互式缩放 map

docker - 在 Docker 容器/静默安装的 Ubuntu 20.04 上安装 Erlang/Elixir

windows - Erlang 应用程序在 Windows 服务器上启动

mysql - Erlang 和 mysql

erlang - 从 mnesia 集群中删除 not_exist_already 节点(方案)

android - toast 不工作

r - 在 map 上绘制插值数据