如何将一个数组转换为DOM树、如何将DOM树转换为数组

146 阅读3分钟

如何将一个数组转换为树

JS代码

        function convert(arr) {
            // 用于 id 和 treeNode 的映射
            const idToTreeNode = new Map();
            
            let root = null; // 返回树的根节点(tree rootNode)
            arr.forEach(item => {
                const { id, name, parentId } = item;

                // 定义 tree node 并加入 map
                const treeNode = { id, name };
                idToTreeNode.set(id, treeNode)

                // 找到 parentNode 并加入到它的 children
                const parentNode = idToTreeNode.get(parentId);
                if (parentNode) {
                    if (parentNode.children == null) parentNode.children = []
                    parentNode.children.push(treeNode)

                }

                // 找到根节点
                if (parentId === 0) {
                    root = treeNode
                }
            })
            return root
        }

        const arr = [
            { id: 1, name: '部门A', parentId: 0 }, // 0 代表顶级节点,无父节点
            { id: 2, name: '部门B', parentId: 1 },
            { id: 3, name: '部门C', parentId: 1 },
            { id: 4, name: '部门D', parentId: 2 },
            { id: 5, name: '部门E', parentId: 2 },
            { id: 6, name: '部门F', parentId: 3 }
        ]

        const tree = convert(arr);
        console.log(tree);

TS代码

/**
 * @description array to tree
 * @author xiaohui
 */
interface IArrayItem {
    id:number,
    name:string,
    parentId:number
}
interface ITreeNode {
    id:number,
    name:string,
    children?:ITreeNode[]
}

function convert(arr:IArrayItem[]):ITreeNode|null{
    // 用于 id 和 treeNode 的映射
    const idToTreeNode:Map<number,ITreeNode> = new Map();
    let root = null; // 返回树的根节点(tree rootNode)
    arr.forEach(item=>{
        const {id,name,parentId} = item;

        // 定义 tree node 并加入 map
        const treeNode:ITreeNode = {id,name};
        idToTreeNode.set(id,treeNode)

        // 找到 parentNode 并加入到它的 children
        const parentNode = idToTreeNode.get(parentId);
        if(parentNode){
            if(parentNode.children == null) parentNode.children = []
            parentNode.children.push(treeNode)
            
        }

        // 找到根节点
        if(parentId ===0) root = treeNode
    })
    return root
}

const arr = [
    {id:1,name:'部门A',parentId:0}, // 0 代表顶级节点,无父节点
    {id:2,name:'部门B',parentId:1},
    {id:3,name:'部门C',parentId:1},
    {id:4,name:'部门D',parentId:2},
    {id:5,name:'部门E',parentId:2},
    {id:6,name:'部门F',parentId:3}
]

const tree = convert(arr);
console.log(tree);

如何将一个树转换为数组

JS代码

        function convert1(root){
            // 使用 Map 映射当前节点和父节点的关系
            const nodeToParent = new Map();

            const arr = [];

            // 广度优先遍历,使用队列 queue (队列先进先出)
            const queue = []; // 数组(使用链表实现队列性能更高一些)
            queue.unshift(root); // 根节点入队

            while (queue.length > 0) {
                const curNode = queue.pop(); // 出队
                if (curNode == null) break;

                const { id, name, children = [] } = curNode;

                // 创建数组 item 并 push
                const parentNode = nodeToParent.get(curNode) // 获取数据
                // 加一个判断
                const parentId = parentNode?.id || 0 // 有值取值,没值取 0
                const item = { id, name, parentId };
                arr.push(item) // 这里处理好的是根节点

                // 子节点入队
                children.forEach(child => {
                    // 映射 parent
                    nodeToParent.set(child, curNode);

                    // 入队
                    queue.unshift(child)
                })
            }
            return arr
        }


        // 功能测试
        const obj = {
            id: 1,
            name: '部门A',
            children: [
                {
                    id: 2,
                    name: '部门B',
                    children: [
                        { id: 4, name: '部门D' },
                        { id: 5, name: '部门E' }
                    ]
                },
                {
                    id: 3,
                    name: '部门C',
                    children: [
                        { id: 6, name: '部门F' }
                    ]
                }
            ]
        }

        const arr1 = convert1(obj);
        console.log(arr1);

TS代码

/**
 * @description tree to array
 * @author xiaohui
 */

interface IArrayItem {
    id: number,
    name: string,
    parentId: number
}
interface ITreeNode {
    id: number,
    name: string,
    children?: ITreeNode[]
}

function convert1(root: ITreeNode): IArrayItem[] {
    // 使用 Map 映射当前节点和父节点的关系
    const nodeToParent: <ITreeNode, ITreeNode> = new Map();

    const arr: IArrayItem[] = [];

    // 广度优先遍历,使用队列 queue (队列先进先出)
    const queue: ITreeNode[] = []; // 数组(使用链表实现队列性能更高一些)
    queue.unshift(root); // 根节点入队

    while (queue.length > 0) {
        const curNode = queue.pop(); // 出队
        if (curNode == null) break;

        const { id, name, children = [] } = curNode;

        // 创建数组 item 并 push
        const parentNode = nodeToParent.get(curNode) // 获取数据
        // 加一个判断
        const parentId = parentNode?.id || 0 // 有值取值,没值取 0
        const item = { id, name, parentId };
        arr.push(item) // 这里处理好的是根节点

        // 子节点入队
        children.forEach(child=>{
            // 映射 parent
            nodeToParent.set(child,curNode);

            // 入队
            queue.unshift(child)
        })
    }
    return arr
}


// 功能测试
const obj = {
    id: 1,
    name: '部门A',
    children: [
        {
            id: 2,
            name: '部门B',
            children: [
                { id: 4, name: '部门D' },
                { id: 5, name: '部门E' }
            ]
        },
        {
            id: 3,
            name: '部门C',
            children: [
                { id: 6, name: '部门F' }
            ]
        }
    ]
}

const arr1 = convert1(obj);
console.log(arr1);