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

如何在JavaScript中删除指定节点并将其子节点移动到目标祖先节点?

实现方案

需求梳理

你需要完成树形结构的节点提升操作,逻辑如下:

  • 定位id为n10的目标节点
  • 提取目标节点的所有子节点
  • 从目标节点的父节点(id为n3,name为William Harvey)的children数组中删除目标节点
  • 将目标节点的子节点追加到父节点的children数组中

原有代码问题

你编写的递归逻辑存在3个核心问题:

  1. forEach循环的return只会终止当前循环项的执行,既不会中断整个循环,也不会把返回值传递给外层的process函数,所以最终调用process永远返回undefined
  2. 没有记录当前遍历节点的父级数组引用,找到n10后无法定位到要修改的n3的children数组
  3. 没有提前终止递归的逻辑,就算找到了目标节点,递归还会继续执行多余的遍历

修复后可运行代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 18:48:00