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

JavaScript从对象数组生成嵌套树,同层级多子节点时递归逻辑失效如何解决?

问题原因分析
  • 第一,你的findNode递归逻辑存在核心缺陷:
    1. 当节点存在子节点时,你没有先校验当前节点是否是要找的父节点,直接递归了最后一个子节点,跳过了当前节点的匹配逻辑
    2. 你仅递归了当前节点的最后一个子节点,没有遍历所有子节点,导致同层级的其他节点完全不会被检索,所以P1插入C2之后,再处理C1时,递归直接进入C2的子节点查找,不会判断P1本身就是C1的父节点,自然无法插入成功
  • 第二,现有排序逻辑不完整:仅将顶级节点前置,没有保证子节点的处理顺序晚于父节点,如果子节点比父节点先被遍历,会出现找不到父节点无法插入的问题。
修正方案

方案1:最小改动修复原有逻辑

仅修改findNode函数,调整为遍历所有子节点、优先校验当前节点是否匹配的逻辑即可解决问题:

public findNode(ele, obj){
  // 先校验当前节点是不是目标父节点
  if(ele.name === obj.parentGroup){
    ele.children.push({name: obj.groupName, children: []});
    // 找到就返回,避免无效重复查找
    return true;
  }
  // 遍历所有子节点递归查找
  for(let child of ele.children){
    if(this.findNode(child, obj)){
      return true;
    }
  }
  return false;
}

方案2:更高效的实现(推荐)

不需要提前排序,也不需要递归遍历整个树查找,用哈希表存储所有节点映射,两次遍历即可完成组装,时间复杂度仅为O(n),性能远高于原有递归查找方案:

function buildTree(inputs) {
  // 存储groupName到节点对象的映射表
  const nodeMap = {};
  // 存储最终的顶级节点数组
  const rootNodes = [];

  // 第一次遍历:初始化所有节点,存入映射表
  inputs.forEach(item => {
    nodeMap[item.groupName] = {
      name: item.groupName,
      children: []
    };
  });

  // 第二次遍历:组装父子关系
  inputs.forEach(item => {
    const currentNode = nodeMap[item.groupName];
    if(item.parentGroup === "null"){
      rootNodes.push(currentNode);
    }else{
      nodeMap[item.parentGroup].children.push(currentNode);
    }
  });

  return rootNodes;
}

// 调用示例
const finalArr = buildTree(inputs);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 06:54:03