如何在JavaScript中删除指定节点并将其子节点移动到目标祖先节点?
实现方案
需求梳理
你需要完成树形结构的节点提升操作,逻辑如下:
- 定位id为
n10的目标节点 - 提取目标节点的所有子节点
- 从目标节点的父节点(id为
n3,name为William Harvey)的children数组中删除目标节点 - 将目标节点的子节点追加到父节点的children数组中
原有代码问题
你编写的递归逻辑存在3个核心问题:
forEach循环的return只会终止当前循环项的执行,既不会中断整个循环,也不会把返回值传递给外层的process函数,所以最终调用process永远返回undefined- 没有记录当前遍历节点的父级数组引用,找到
n10后无法定位到要修改的n3的children数组 - 没有提前终止递归的逻辑,就算找到了目标节点,递归还会继续执行多余的遍历
修复后可运行代码
let all = [ { id: "n1", name: "Hipokrat", children: [ { id: "n2", name: "Edward Janner", children: [ { id: "n9", name: "Edison, Thomas", } ] } ] }, { id: "n3", name: "William Harvey", children: [ { id: "n10", name: "Lister, Joseph", children: [ { id: "n11", name: "Kant, Immanuel", children: [ { id: "n15", name: "Rawls, John" }, { id: "n46", name: "More, Thomas" }, { id: "n47", name: "Galen" } ] } ] }, { id: "n12", name: "Smith, Adam" } ] }, { id: "n48", name: "Osler, William", children: [ { id: "n51", name: "Louis Pasteur" } ] }, { id: "n52", name: "John Hunter", children: [ { id: "n53", name: "Freud, Sigmund" } ] } ]; // 递归查找并提升节点 function liftNode(tree, targetId) { // 遍历当前层级所有节点 for (let i = 0; i < tree.length; i++) { const node = tree[i]; // 匹配到目标节点 if (node.id === targetId) { const targetChildren = node.children || []; // 从父级数组删除目标节点 tree.splice(i, 1); // 将目标节点的子节点插入父级数组 tree.push(...targetChildren); return true; // 找到目标直接终止递归 } // 递归遍历子节点 if (node.children?.length) { const found = liftNode(node.children, targetId); if (found) return true; // 子层级找到直接终止所有递归 } } return false; } // 执行操作:提升id为n10的节点的子节点 liftNode(all, "n10"); // 打印结果验证 console.log(JSON.stringify(all, null, 2));
逻辑说明
- 用
for循环代替forEach,可以通过return直接中断遍历和递归,性能更优 - 递归时直接传递当前节点所在的数组引用,找到目标节点后直接用
splice删除目标,再用展开运算符...把子节点插入到父数组 - 找到目标后立刻返回
true终止所有递归,避免不必要的遍历
运行代码后,all变量就会得到你预期的结构。
内容的提问来源于stack exchange,提问作者sundowatch
相关产品推荐
相关产品推荐

