美文网首页vue
js数组平铺和树形结构的转换

js数组平铺和树形结构的转换

作者: 丿Sorry丶 | 来源:发表于2020-04-28 16:34 被阅读0次

    将一个平铺的数据转换成一个树形的数据结构

    /*
        将一个平铺的数据转换成一个树形的数据结构
     config={
        id:id,     //对象id
        parentId:parentId    //父元素对象ID
        childrenList:childrenList     //树形属性名称[]
     }
     */
    module.exports.convertArrayToTree = function (data,c) {
    
        if (!Array.isArray(data)) {
            throw new TypeError('array-unique expects an array.');
        }
    
        let config = {
            id:c.id?c.id:"id",
            parentId:c.parentId?c.parentId:"parentId",
            childrenList:c.childrenList?c.childrenList:"childrenList",
        };
    
        var childrenListMap = {};   //
        var nodeIds = {};   //将每一个数据项存储为一个对象
        var tree = [], count = 0, total = 0;    // tree 返回数据
    
        for (let d of data) {       //求出子元素列表对象
            let parentId = d[config.parentId];
            if (childrenListMap[parentId] == null) {
                childrenListMap[parentId] = [];
            }
            nodeIds[d[config.id]] = d;
            childrenListMap[parentId].push(d);
        }
    
        total = Object.keys(childrenListMap).length;    //总共需要几次操作
    
        for (let d of data) {      //初始化tree
            let parentId = d[config.parentId];
            if (nodeIds[parentId] == null) {
                tree.push(d);
            }
        }
    
        for (let t of tree) {
            if (count == total) {
                break;
            }
            adaptToChildrenList(t);
        }
    
        function adaptToChildrenList(o) {      //开始拼接数据
            if (childrenListMap[o[config.id]] !== null) {
                o[config.childrenList] = childrenListMap[o[config.id]];
                count++;
                if (count == total) {
                    return;
                }
            }
            if (o[config.childrenList]) {
                for (let c of o[config.childrenList]) {
                    if (count == total) {
                        break;
                    }
                    adaptToChildrenList(c);
                }
            }
        }
        return tree;
    };
    
    export function construct(nodes, config) {
        const id = config && config.id || 'id'
        const pid = config && config.pid || 'parentid'
        const children = config && config.children || 'children'
    
        const idMap = {}
        const jsonTree = []
    
        nodes.forEach((v) => { v && (idMap[v[id]] = v) })
        nodes.forEach((v) => {
            if (v) {
                let parent = idMap[v[pid]]
                if (parent) {
                    !parent[children] && (parent[children] = [])
                    parent[children].push(v)
                } else {
                    jsonTree.push(v)
                }
            }
        })
    
        return jsonTree
    }
    

    将树形结构的数组转换成平铺的数组

    /*
       将树形结构的数组转换成平铺的数组
     */
    
    module.exports.convertTreeToArray = function (data,c) {
    
        if (!Array.isArray(data)) {
            throw new TypeError('array-unique expects an array.');
        }
    
    
        let config = {
            needDelete:c.needDelete?c.needDelete:false,
            childrenList:c.childrenList?c.childrenList:"childrenList"
        };
    
        let array = [];
    
        function convert(data) {
            let n = Object.assign({},data);
            config.needDelete && delete n[config.childrenList];
            array.push(n);
    
            if(data[config.childrenList]){
                for(let c of data[config.childrenList]){
                    convert(c);
                }
            }
        }
        for(let d of data){
            convert(d);
        }
    
        return array;
    };
    
    export function destruct(forest, config) {
        const id = config && config.id || 'id'
        const pid = config && config.pid || 'pid'
        const children = config && config.children || 'children'
    
        function flatTree(tree) {
            const queue = [tree]
            const result = []
            while (queue.length) {
                let currentNode = queue.shift()
                if (currentNode.hasOwnProperty(id)) {
                    if (!currentNode.hasOwnProperty(pid)) {
                        currentNode = { ...currentNode, [pid]: null }
                    }
                    if (currentNode[children]) {
                        currentNode[children].forEach((v) => { v && queue.push({ ...v, [pid]: currentNode[id] }) })
                    }
                    result.push(currentNode)
                    delete currentNode[children]
                } else {
                    throw new Error('you need to specify the [id] of the json tree')
                }
            }
            return result
        }
    
        if (Array.isArray(forest)) {
            return forest.map((v) => flatTree(v)).reduce((pre, cur) => pre.concat(cur))
        } else {
            return flatTree(forest)
        }
    }
    
    

    相关文章

      网友评论

        本文标题:js数组平铺和树形结构的转换

        本文链接:https://www.haomeiwen.com/subject/fthbwhtx.html