You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform如何合并含重复键的映射列表且不覆盖值

深度合并嵌套映射列表(重复键追加值而非覆盖)

问题说明

我有一个包含重复键的嵌套映射列表,需要将其合并为单个映射。对于重复的键,要求追加合并其对应的嵌套值,而不是用最新的映射值覆盖旧值。

输入示例

input_maps = [
    {
        "e-p": {
             "a-emea": {
                "n@abc.com": {
                    "role": "READER"
                 }
              },
             "c-emea": {
                 "n@abc.com": {
                    "role": "READER"
                  }
              }
        },
        "g-p": {
            "a-global": {
                "n@abc.com": {
                    "role": "READER"
                 }
             }
         }
    },
   {},
   {
        "g-p": {
            "a-global": {
                "r@abc.com": {
                    "role": "READER"
                 }
             },
            "d-global": {
                "r@abc.com": {
                    "role": "READER"
                }
             }
         },
        "u-p": {
            "a-us": {
                "r@abc.com": {
                    "role": "READER"
                }
            }
         }
  
    },
]

期望输出

output_maps = {
    "e-p": {
        "a-emea": {
            "n@abc.com": {
                "role": "READER"
             }
         },
         "c-emea": {
             "n@abc.com": {
                 "role": "READER"
              }
          }
        },
    "g-p": {
        "a-global": {
            "n@abc.com": {
                "role": "READER"
             },
            "r@abc.com": {
                "role": "READER"
            }
         },
        "d-global": {
            "r@abc.com": {
                "role": "READER"
            }
        }
     },
    "u-p": {
        "a-us": {
            "r@abc.com": {
                "role": "READER"
            }
        }
    }
  }

尝试过的代码(存在覆盖问题)

output_maps = merge([
    for input_map in local.input_maps:{
        for key, value in input_map => {
            for sub_key, sub_value in value : sub_key => sub_value
            }
        }
    ]...)

这段代码用Terraform内置的merge函数做浅合并,遇到重复键(如g-p)时,会直接用后面的映射值覆盖前面的,无法实现嵌套层级的深度合并。

解决方案:递归深度合并

通过定义递归的合并函数,实现嵌套映射的深度合并,具体代码如下:

locals {
    # 递归合并两个嵌套映射:遇到相同键时继续合并子映射,而非覆盖
    deep_merge = func(a, b) {
        # 若输入不是映射类型,直接返回b(适配非嵌套场景)
        if type(a) != object({}) || type(b) != object({}) {
            return b
        }
        # 合并所有键,共同键递归处理子映射
        return merge(
            a,
            b,
            {
                for k in setintersection(keys(a), keys(b)) : k => local.deep_merge(a[k], b[k])
            }
        )
    }

    # 遍历列表中的所有映射,依次执行深度合并
    output_maps = foldl(local.input_maps, {}, acc, m) => local.deep_merge(acc, m)
}

代码说明

  1. deep_merge函数:递归处理两个映射,当遇到相同键时,会继续合并它们的子映射,确保嵌套层级的内容被追加而非覆盖。
  2. foldl函数:将列表中的所有映射逐个传入deep_merge,从空映射开始累积合并结果,最终得到完整的合并后映射。

这个方法可以完美实现需求中的嵌套映射合并,比如g-p下的a-global会合并两个邮箱的角色条目,而不是替换原有内容。

内容的提问来源于stack exchange,提问作者neha sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 10:17:53