将乱序的一维数组根据parentId转化为树形结构,子节点放在children下

// 数据
let a = [
    {
        id: "050207",
        parentId: "0502",
        children: []
    },
    {
        id: "050208",
        parentId: "0502",
        children: []
    },
    {
        id: "01",
        parentId: "0",
        children: []
    },
    {
        id: "02",
        parentId: "0",
        children: []
    },
    {
        id: "050209",
        parentId: "0502",
        children: []
    },
    {
        id: "0201",
        parentId: "02",
        children: []
    },

    {
        id: "05",
        parentId: "0",
        children: []
    },
    {
        id: "0501",
        parentId: "05",
        children: []
    },
    {
        id: "0502",
        parentId: "05",
        children: []
    },
    {
        id: "050201",
        parentId: "0502",
        children: []
    },
    {
        id: "050202",
        parentId: "0502",
        children: []
    },
    {
        id: "050203",
        parentId: "0502",
        children: []
    },
    {
        id: "050204",
        parentId: "0502",
        children: []
    },
    {
        id: "050205",
        parentId: "0502",
        children: []
    },
    {
        id: "050206",
        parentId: "0502",
        children: []
    }
]
// 函数
function buildTreeOptimized(nodes) {
    const nodeMap = new Map();  // 哈希表存储所有节点
    const roots = [];           // 存储顶层节点
    const duplicates = new Set(); // 检测重复ID

    // 第一次遍历: 注册所有节点 & 检测重复
    for (const node of nodes) {
        const id = node.id;
      
        // 循环引用检测
        if (node.id === node.parentId) {
            throw new Error(`循环引用: ${node.id} -> ${node.parentId}`);
        }

        // 重复ID检测
        if (nodeMap.has(id)) {
            duplicates.add(id);
            continue;
        }

        // 初始化子节点数组
        node.children = [];
        nodeMap.set(id, node);
    }

    // 输出重复警告
    if (duplicates.size > 0) {
        console.warn(`检测到重复ID: ${Array.from(duplicates).join(', ')}`);
    }

    // 第二次遍历: 构建树结构
    for (const node of nodes) {
        const { parentId } = node;

        // 跳过已处理的重复节点
        if (duplicates.has(node.id)) continue;

        if (parentId === '0') {
            roots.push(node);  // 顶层节点
        } else if (parentId) {
            const parent = nodeMap.get(parentId);
            parent ?.children.push(node); // 挂载子节点
        } else {
            console.warn(`孤儿节点 ${node.id}: parentId为空`);
        }
    }

    return roots;
}

// 使用示例
const tree = buildTreeOptimized(a);
console.log(tree);

image.png


兔子先森
419 声望18 粉丝

致力于新技术的推广与优秀技术的普及。