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

如何在键为字符串值为数组的Map中包含父节点(JavaScript)

问题:遍历树结构构建父节点Map时数组值被覆盖

我尝试遍历一棵树木并创建一个Map数据结构,用于存储元素的父节点列表,格式为键{子元素名称}:值{父节点名称数组}。

我的代码如下:

global.parentMap =  new Map()

function readTree(root) {
  let queue = [root];
  while (queue.length > 0) {
      let node = queue.shift();
      for (let childType in node.children) {
          for (let child of node.children[childType]) {
              let newChild = {...child};
              queue.push(newChild);
              if(global.parentMap.has(newChild.item.name)){
                 global.parentMap.set(newChild.item.name,global.parentMap.get(newChild.item.name).push(node.item.name))}
              if(!parentMap.has(newChild)){
                global.parentMap.set(newChild.item.name,[]);
              }
              console.log("Parent"+node.item.name+" has childs "+newChild.item.name)
               global.parentMap.get(newChild.item.name).push(node.item.name);

    
            }
      }
  }
}

问题在于新的父节点无法被推入Map的数组值中,总是被覆盖。控制台输出如下:

Parent: testing_group has childs:command_name
Parent: agv_commands has childs:location_name
Parent: agv_commands has childs:header_frame_id
Parent: agv_commands has childs:location_coordinates
Parent: agv_commands has childs:robot_name
Parent: agv_commands has childs:load_id
Parent: agv_commands has childs:command_item
Parent: agv_commands has childs:command_name
Map(7) {
  'command_name' => [ 'agv_commands' ], // 本应包含testing_group
  'location_name' => [ 'agv_commands' ],
  'header_frame_id' => [ 'agv_commands' ],
  'location_coordinates' => [ 'agv_commands' ],
  'robot_name' => [ 'agv_commands' ],
  'load_id' => [ 'agv_commands' ],
  'command_item' => [ 'agv_commands' ]
}
问题分析与修复

错误原因:

  1. push返回值误用:global.parentMap.get(...).push(...)中,push方法返回的是数组的新长度,不是数组本身。你用set把这个长度存进Map,导致后续操作完全错误。
  2. 判断条件错误:if(!parentMap.has(newChild))判断的是newChild对象,但Map的键是子元素名称字符串,应该判断!global.parentMap.has(newChild.item.name),而且这个判断的顺序也不对。
  3. 重复执行push:代码里先在if里执行了一次push(虽然逻辑错了),后面又重复push,导致逻辑混乱。

修复后的代码:

global.parentMap = new Map()

function readTree(root) {
  let queue = [root];
  while (queue.length > 0) {
      let node = queue.shift();
      for (let childType in node.children) {
          for (let child of node.children[childType]) {
              let newChild = {...child};
              queue.push(newChild);
              const childName = newChild.item.name;
              const parentName = node.item.name;
              
              // 先初始化空数组(如果子节点还没在Map里)
              if (!global.parentMap.has(childName)) {
                  global.parentMap.set(childName, []);
              }
              
              // 直接向数组添加父节点,数组是引用类型,修改后Map里的值会同步更新
              global.parentMap.get(childName).push(parentName);
              
              console.log(`Parent: ${parentName} has childs: ${childName}`);
            }
      }
  }
}

修复说明:

  • 移除了错误的set操作:因为数组是引用类型,直接get到数组后执行push,Map里的数组会自动更新,不需要重新set。
  • 修正了初始化数组的判断条件:确保针对子元素名称判断,且在添加父节点前完成初始化。
  • 删除了重复的push操作,避免冗余逻辑。
  • 用模板字符串优化了日志输出,可读性更强。

修复后,command_name对应的数组会正确包含['testing_group', 'agv_commands'],符合预期。

内容的提问来源于stack exchange,提问作者Θοδωρής Σουλτανόπουλος

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 09:40:30