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

如何过滤无限嵌套对象数组?移除指定ID节点及其子节点

移除无限嵌套数组中指定ID节点的最优方案

给定如下无限嵌套的对象数组:

const data = [
    {
        id: 1,
        children:[
            {
                id: 2,
                children:[
                    {
                        id: 3,
                        children:[
                            {
                                id: 4,
                                children: [],
                            },
                            {
                                id: 5,
                                children: [],
                            }
                        ],
                    },
                ],
            },
        ],
    },
    {
        id: 8,
        children:[
            {
                id: 9,
                children:[
                    {
                        id: 10,
                        children: [],
                    },
                ],
            },
        ],
    },
];

需要移除指定ID(比如ID=3)及其所有子节点,返回新数组,处理后结果如下:

const result = [
    {
        id: 1,
        children:[
            {
                id: 2,
                children: [],
            },
        ],
    },
    {
        id: 8,
        children:[
            {
                id: 9,
                children:[
                    {
                        id: 10,
                        children: [],
                    },
                ],
            },
        ],
    },
];

最优实现方案

直接用递归+reduce的纯函数方案,逻辑清晰且不会修改原数据,代码如下:

function removeNodeById(data, targetId) {
  return data.reduce((acc, node) => {
    // 匹配到目标ID,直接跳过该节点
    if (node.id === targetId) {
      return acc;
    }
    // 复制当前节点,递归处理子节点数组
    const newNode = {
      ...node,
      children: removeNodeById(node.children || [], targetId)
    };
    acc.push(newNode);
    return acc;
  }, []);
}

// 使用示例
const processedData = removeNodeById(data, 3);

方案说明

  1. 纯函数特性:整个过程不会修改原数组和节点,返回全新的数组,避免副作用导致的意外问题
  2. 递归处理嵌套:天然适配无限嵌套的结构,不管目标节点在第几层,都能精准定位并移除
  3. 简洁高效:用reduce遍历数组构建结果,代码简洁,时间复杂度为O(n)(n为所有节点总数)
  4. 鲁棒性:通过node.children || []处理节点没有children属性的情况,避免报错

极端场景补充

如果你的数据层级极深(超过JS引擎递归栈限制,一般是几万层),可以把递归改成迭代版,用栈来模拟递归过程,示例如下:

function removeNodeByIdIterative(data, targetId) {
  const stack = [...data];
  const result = [];
  const parentMap = new Map(); // 记录节点的父级数组

  // 初始化根节点的父级映射
  data.forEach(node => parentMap.set(node, result));

  while (stack.length > 0) {
    const node = stack.pop();
    if (node.id === targetId) {
      // 找到目标节点,从父级数组中移除
      const parentArr = parentMap.get(node);
      const index = parentArr.findIndex(n => n.id === node.id);
      if (index !== -1) {
        parentArr.splice(index, 1);
      }
      continue;
    }
    // 复制节点,处理子节点
    const newNode = { ...node, children: [] };
    const parentArr = parentMap.get(node);
    parentArr.push(newNode);
    // 处理子节点,记录父级映射
    if (node.children && node.children.length > 0) {
      node.children.forEach(child => {
        parentMap.set(child, newNode.children);
        stack.push(child);
      });
    }
  }
  return result;
}

不过绝大多数业务场景下,递归方案已经足够高效且易维护,迭代版仅作为极端情况的补充。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 12:20:02