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

如何递归移除对象数组中重复的id=3对象,仅保留id=2子项中的该对象

移除根层级重复节点的可行实现思路

针对你提供的嵌套对象数组,要移除根层级中已作为子节点存在的id=3对象,以下是几种实用的实现思路:

思路1:先收集子树所有ID,再过滤根节点

核心逻辑是先把所有嵌套子节点的ID收集起来,再从根数组中剔除那些ID已存在于子树中的元素。

// 递归收集所有子树节点的ID
function collectChildNodeIds(nodes) {
  const idSet = new Set();
  const traverse = (node) => {
    node.children.forEach(child => {
      idSet.add(child.id);
      traverse(child);
    });
  };
  nodes.forEach(traverse);
  return idSet;
}

// 执行过滤
const childIds = collectChildNodeIds(data);
const filteredData = data.filter(item => !childIds.has(item.id));

思路2:闭包内维护ID集合,先标记子节点再过滤根节点

利用闭包保存已出现的子节点ID,先遍历所有子节点完成标记,最后对根数组做过滤。

function removeDuplicateRoots(data) {
  const existingChildIds = new Set();

  // 遍历所有子节点,标记已存在的ID
  const markChildIds = (nodes) => {
    nodes.forEach(node => {
      node.children.forEach(child => {
        existingChildIds.add(child.id);
        markChildIds([child]);
      });
    });
  };

  markChildIds(data);
  // 过滤根节点,移除已在子树中出现的ID
  return data.filter(node => !existingChildIds.has(node.id));
}

const result = removeDuplicateRoots(data);

思路3:深度优先遍历,边处理子树边构建结果

在遍历过程中先处理子节点并标记ID,再判断当前根节点是否需要保留,一步完成结果构建,避免额外的遍历步骤。

function filterDuplicateRootNodes(data) {
  const existingIds = new Set();
  const result = [];

  const processSubtree = (node) => {
    // 先递归处理子节点,标记所有子节点ID
    node.children.forEach(child => {
      existingIds.add(child.id);
      processSubtree(child);
    });
  };

  data.forEach(node => {
    processSubtree(node);
    // 根节点ID未在子树中出现过,才加入结果
    if (!existingIds.has(node.id)) {
      result.push(node);
    }
  });

  return result;
}

const result = filterDuplicateRootNodes(data);

内容的提问来源于stack exchange,提问作者Đạt Huỳnh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:35:30