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

如何将含嵌套数组的对象数组转换为扁平对象数组?

嵌套数组对象的扁平化转换解决方案

问题描述

现有如下JavaScript数组:

let testData = [
  {
    MC: "11233",
    jobid: 113331,
    list: [
      { Q1: 1113, Q2: 333, code: "thisis1" },
      { Q1: 333, Q2: 111, code: "thisis2" },
      { Q1: 333, code: "thisis3" },
    ],
  },
  {
    MC: "332211",
    jobid: 3333,
    list: [
      { Q1: 444, Q2: 555, code: "thisis4" },
    ],
  },
];

需要将其转换为扁平化的数组结构:

[
  { MC: "11233", jobid: 113331, Q1: 1113, Q2: 333, code: "thisis1" },
  { MC: "11233", jobid: 113331, Q1: 333, Q2: 111, code: "thisis2" },
  { MC: "11233", jobid: 113331, Q1: 333, code: "thisis3" },
  { MC: "332211", jobid: 3333, Q1: 444, Q2: 555, code: "thisis4" },
]

尝试的代码及问题

尝试了如下递归实现,但未达到预期:

let newData = [];
testData.forEach((element, index) => {
  let flattedObj = {};
  deconstructeArrayObject(flattedObj, element);
});
const deconstructeArrayObject = (flattedObj, targetObj) => {
  let tempArr = [];
  for (let key in targetObj) {
    if (Array.isArray(targetObj[key])) {
      targetObj[key].forEach((element) => {
        tempArr.push(
          ...JSON.parse(
            JSON.stringify(
              deconstructeArrayObject(flattedObj, element, outputArray)
            )
          )
        );
      });
    } else {
      flattedObj[key] = targetObj[key];
    }
  }
  return flattedObj; // actually I want this function to return an array
};

现有代码的核心问题:

  • 递归函数逻辑冲突:既修改传入的flattedObj,又试图返回数组,导致状态混乱
  • 未正确合并父对象属性与子数组元素属性,也未将结果推入目标数组
  • 冗余使用JSON.parse(JSON.stringify()),无必要且可能引发意外

解决方案

方案1:固定结构的循环实现(直观高效)

针对当前固定的结构(每个对象包含list数组和其他普通属性),直接遍历处理即可:

const flattenData = (data) => {
  const result = [];
  data.forEach(item => {
    // 提取除list外的所有属性
    const { list, ...baseProps } = item;
    // 遍历list中的每个元素,合并属性后加入结果数组
    list.forEach(subItem => {
      result.push({ ...baseProps, ...subItem });
    });
  });
  return result;
};

// 使用示例
const newData = flattenData(testData);
console.log(newData);

方案2:通用递归实现(适配复杂嵌套)

如果未来数据结构可能有多层嵌套数组,可使用递归处理任意层级的数组属性:

const flattenRecursive = (obj, parentProps = {}) => {
  let result = [];
  const currentProps = { ...parentProps };

  for (const key in obj) {
    if (Array.isArray(obj[key])) {
      // 遇到数组,遍历每个元素递归处理,合并当前已收集的属性
      obj[key].forEach(subObj => {
        result = [...result, ...flattenRecursive(subObj, currentProps)];
      });
    } else {
      // 普通属性,添加到当前属性集合
      currentProps[key] = obj[key];
    }
  }

  // 若当前对象无数组属性,将当前属性对象作为结果返回
  if (result.length === 0) {
    result.push(currentProps);
  }

  return result;
};

// 使用示例
const newData = [];
testData.forEach(item => {
  newData.push(...flattenRecursive(item));
});
console.log(newData);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 08:54:18