如何将含嵌套数组的对象数组转换为扁平对象数组?
嵌套数组对象的扁平化转换解决方案
问题描述
现有如下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
相关产品推荐
相关产品推荐

