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

如何递归扁平化对象数组?多维对象数组转一维实现咨询

嘿,这个需求我平时做前端或者数据处理时经常碰到,给你两种靠谱的解决方案,不管是递归还是迭代方式,都能把你的嵌套对象数组转成一维,让所有父元素和子元素都处于同一层级。

递归实现方案

递归是最直观的方式,逻辑很简单:遍历数组里的每个元素,先把当前元素加入结果数组,然后如果这个元素有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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:06:27