如何在Erlang嵌套Map中仅替换指定值并保留其余内容?
Erlang 深层嵌套Map的叶子节点更新方案
要实现仅更新深层嵌套Map的指定叶子节点、保留其余内容的需求,你可以通过**递归结合maps:merge_with/3**来实现深层合并,而非使用浅层的maps:merge/2。
问题回顾
你当前使用maps:merge/2的结果会直接替换整个子Map:
> maps:merge(#{a => apple, b => #{c => cherry, d => date}}, #{b => #{c => cantaloupe}}). #{a => apple, b => #{c => cantaloupe}}
而期望保留子Map中未被更新的键(比如d => date),得到:
#{a => apple, b => #{c => cantaloupe, d => date}}
解决方案:递归深层合并函数
实现一个递归的deep_merge/2函数,利用maps:merge_with/3的自定义合并逻辑,对嵌套的子Map进行递归处理:
deep_merge(Map1, Map2) -> maps:merge_with( fun(_Key, Val1, Val2) when is_map(Val1), is_map(Val2) -> % 若两个值都是Map,递归合并子Map deep_merge(Val1, Val2); (_Key, _Val1, Val2) -> % 非Map值直接用Map2的值覆盖 Val2 end, Map1, Map2 ).
测试验证
调用这个函数即可得到你想要的结果:
> deep_merge(#{a => apple, b => #{c => cherry, d => date}}, #{b => #{c => cantaloupe}}). #{a => apple, b => #{c => cantaloupe, d => date}}
逻辑说明
- 当合并过程中遇到两个键对应的值都是Map时,递归调用
deep_merge/2继续合并子Map,避免直接替换整个子结构; - 当值不是Map时,直接用第二个Map(更新值的Map)中的值覆盖第一个Map的值,实现叶子节点的更新。
内容的提问来源于stack exchange,提问作者Fylke
相关产品推荐
相关产品推荐

