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

如何在JavaScript中递归归并结构对称的对象数组?

递归归并对称结构化数据的实现方案

需求说明

需要将一组结构对称的嵌套数据递归归并,把相同层级同key的零散值收集到数组中,深层嵌套结构保持对应层级的归并逻辑。

原始输入数据

const data = [
  {
    name: 'Bob',
    relations: {
      siblings: [
        {
          name: 'Tom',
          age: '20',
          snacks: [
            {
              type: 'yogurt'
            }
          ]
        },
        {
          name: 'Jacob',
          snacks: [
            {
              type: 'cookie',
              amount: '2'
            },
            {
              type: 'brownie',
              amount: '3'
            }
          ]
        }
      ]
    }
  },
  {
    name: 'Robert',
    relations: {
      siblings: [
        {
          name: 'Timmy',
          age: '16',
          snacks: [
            {
              type: 'fudge'
            },
            {
              type: 'brownie'
            }
          ]
        }
      ]
    }
  }
];

期望输出结果

const output = {
  name: ['Bob', 'Robert'],
  relations: {
    siblings: {
      name: ['Tom', 'Jacob', 'Timmy'],
      age: ['20', '16'],
      snacks: {
        type: ['yogurt', 'cookie', 'fudge', 'brownie'],
        amount: ['2', '3']
      }
    }
  }
}

现有代码问题

你写的compact函数存在几个核心问题:

  • 参数引用错误:函数参数是value,但内部误用了未定义的object变量
  • 完全跳过数组的递归处理逻辑,无法处理数组类型的嵌套结构
  • 没有实现值的合并逻辑,仅简单覆盖累计对象的key,无法收集多个同key的值
  • 原始类型的处理逻辑错误,没有将值正确收集到数组中

修改后的递归实现代码

const mergeData = (input, accumulator = {}) => {
  // 处理数组:遍历每个元素递归合并
  if (Array.isArray(input)) {
    return input.reduce((acc, item) => mergeData(item, acc), accumulator);
  }

  // 处理原始类型(字符串、数字等):收集到数组并去重
  if (typeof input !== 'object' || input === null) {
    return Array.isArray(accumulator) 
      ? [...new Set([...accumulator, input])] 
      : [input];
  }

  // 处理对象:遍历每个键值对递归合并
  return Object.entries(input).reduce((acc, [key, value]) => {
    // 递归处理当前值,并合并到累计器的对应key中
    acc[key] = mergeData(value, acc[key]);
    return acc;
  }, accumulator);
};

// 使用示例
const output = mergeData(data);
console.log(output);

代码逻辑解释

  1. 数组处理分支:如果输入是数组,用reduce遍历每个元素,将当前元素和累计器传入递归函数,实现逐个元素的归并
  2. 原始类型处理分支:如果输入是字符串、数字等原始类型,将其添加到数组中,用Set去重(匹配你期望输出中重复brownie只保留一次的需求);若累计器已有对应数组,则合并后去重,否则直接生成新数组
  3. 对象处理分支:遍历对象的每个键值对,递归处理当前值,并将结果合并到累计器的对应key中,实现深层嵌套结构的归并
  4. 累计器传递:通过第二个参数accumulator在递归过程中传递已合并的结果,避免重复创建对象,实现逐步合并

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 23:32:02