如何递归扁平化对象数组?多维对象数组转一维实现咨询
嘿,这个需求我平时做前端或者数据处理时经常碰到,给你两种靠谱的解决方案,不管是递归还是迭代方式,都能把你的嵌套对象数组转成一维,让所有父元素和子元素都处于同一层级。
递归实现方案
递归是最直观的方式,逻辑很简单:遍历数组里的每个元素,先把当前元素加入结果数组,然后如果这个元素有children子数组,就递归处理这个子数组,把递归得到的结果合并到主结果里。
function flattenNestedArray(arr) { let flattened = []; arr.forEach(item => { // 先把当前元素加入结果 flattened.push(item); // 如果存在children且是数组,递归处理并合并结果 if (item.children && Array.isArray(item.children)) { flattened = flattened.concat(flattenNestedArray(item.children)); } }); return flattened; } // 用你的示例数组测试 const originalData = [{ "name":"Locations", "children":[{ "name":"U.S." },{ "name":"Canada" },{ "name":"London" }] },{ "name":"Benefits", "children":[{ "name":"U.S. Benefits", "children":[{ "name":"U.S. Benefits at a Glance" },{ "name":"U.S. Holiday Calendar" }] },{ "name":"London Benefits", "children":[{ "name":"London Benefits at a Glance" },{ "name":"London Holiday Calendar" }] },{ "name":"India Benefits", "children":[{ "name":"India Benefits at a Glance" },{ "name":"India Holiday Calendar" }] }] }]; const result = flattenNestedArray(originalData); console.log(result);
运行后,结果数组会包含所有层级的对象:从最顶层的Locations、Benefits,到它们的直接子元素,再到更深层级的子元素,全部处于同一数组中。
迭代(非递归)实现方案
如果你的嵌套层级特别深,递归可能会触发JavaScript的栈溢出错误,这时候用迭代的方式更安全。我们可以用栈来模拟递归的过程:
function flattenNestedArrayIterative(arr) { const flattened = []; // 初始化栈,把原数组的元素都放进去 const stack = [...arr]; while (stack.length > 0) { const currentItem = stack.pop(); // 将当前元素加入结果 flattened.push(currentItem); // 如果有children,反转后压入栈(保证处理顺序和递归一致) if (currentItem.children && Array.isArray(currentItem.children)) { // 反转是因为栈是后进先出,反转后原children的第一个元素会先被处理 stack.push(...currentItem.children.reverse()); } } // 因为栈的处理顺序是倒序的,最后反转结果还原顺序 return flattened.reverse(); } // 测试 const iterativeResult = flattenNestedArrayIterative(originalData); console.log(iterativeResult);
这个方法和递归的结果完全一致,但避免了递归栈深度的限制,适合处理超深嵌套的数据。
可选:移除对象的
children属性 如果你的需求里不需要保留原对象的children字段,可以在加入结果时创建一个新对象,剔除children:
function flattenWithoutChildren(arr) { let flattened = []; arr.forEach(item => { // 解构出children,剩下的属性组成新对象 const { children, ...rest } = item; flattened.push(rest); if (children && Array.isArray(children)) { flattened = flattened.concat(flattenWithoutChildren(children)); } }); return flattened; }
这样得到的每个对象就只有name(或其他原有属性),没有children字段了。
内容的提问来源于stack exchange,提问作者pj013
相关产品推荐
相关产品推荐

