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

如何在AppScript中合并多字典并对公共键对应值求和?

嵌套字典合并(公共键值求和)解决方案

问题场景

你需要在Google Apps Script中合并Dict01、Dict02、Dict03三个嵌套字典,要求同一层级下的公共键对应数值自动求和,非公共键直接保留。

示例输入与期望结果

输入字典

const Dict01 = {
  "A": {"X": 10, "Y": 20},
  "B": {"Z": 30}
};

const Dict02 = {
  "A": {"X": 5, "Z": 15},
  "C": {"Y": 25}
};

const Dict03 = {
  "B": {"Z": 10},
  "C": {"Y": 5, "X": 7}
};

期望合并结果

{
  "A": {"X": 15, "Y": 20, "Z": 15},
  "B": {"Z": 40},
  "C": {"Y": 30, "X": 7}
}

实现代码

下面是通用的递归合并函数,支持任意数量的嵌套字典合并,自动处理数值求和:

function mergeNestedDicts(...dicts) {
  const result = {};
  
  dicts.forEach(dict => {
    Object.keys(dict).forEach(key => {
      if (!result[key]) {
        // 结果中无此键,直接复制(嵌套对象做浅拷贝,避免修改原字典)
        result[key] = typeof dict[key] === 'object' && !Array.isArray(dict[key]) 
          ? {...dict[key]} 
          : dict[key];
      } else {
        // 键已存在,判断类型处理
        if (typeof result[key] === 'number' && typeof dict[key] === 'number') {
          result[key] += dict[key];
        } else if (typeof result[key] === 'object' && typeof dict[key] === 'object' && !Array.isArray(result[key]) && !Array.isArray(dict[key])) {
          // 均为嵌套字典,递归合并子层级
          result[key] = mergeNestedDicts(result[key], dict[key]);
        }
        // 如需处理字符串、数组等其他类型,可在此添加逻辑
      }
    });
  });
  
  return result;
}

// 调用示例
const mergedDict = mergeNestedDicts(Dict01, Dict02, Dict03);
console.log(JSON.stringify(mergedDict, null, 2)); // 打印合并结果

关键逻辑说明

  1. 灵活参数:使用剩余参数...dicts,支持合并2个及以上的嵌套字典,不限于3个。
  2. 递归处理嵌套:遇到子字典时自动递归调用合并函数,确保每一层级的公共键都能正确求和。
  3. 类型安全判断:仅对数值类型执行求和,对嵌套字典执行递归合并,避免数组、字符串等类型干扰。
  4. 原字典保护:对嵌套对象使用{...dict[key]}做浅拷贝,不会修改原始输入字典的数据。

注意事项

  • 如果你的字典中存在非数值、非字典的类型(如字符串、数组),当前代码会跳过合并逻辑,可根据需求添加对应处理(比如字符串拼接、数组合并)。
  • 确保所有嵌套结构都是纯对象(字典),而非数组,数组的合并逻辑需要单独处理。
  • 代码可直接在Google Apps Script编辑器中运行,无需额外依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:32:56