个人封装Tree类

废话少说,直接上代码。

	class Tree {
        static default_key = 'id';				// 关键key
        static default_parentKey = 'parentId';	// 关键key的父key
        static default_initial = '0';			// 祖宗key的值
        constructor(
            {
                list,
                key = Tree.default_key,
                parentKey = Tree.default_parentKey,
                initial = Tree.default_initial,
            }) {
            this.key = key;
            this.parentKey = parentKey;
            this.initial = initial;
            this.data = this.listToTree(list);
            this.setLevelIndex(this.data);
            this.list = list;
        }
        // list转化tree
        listToTree(list) {
            list.forEach(c => {
                c.children = []
                list.forEach(d => {
                    if (c[this.key] === d[this.parentKey]) {
                        c.children.push(d);
                    }
                })
            });
            return list.filter(c => c[this.parentKey] === this.initial);
        }
        // 根据id找到对应节点
        findNode(id) {
            let result = null
            const handle = (id = id, data = this.data) => {
                if (data.length) {
                    for (let i = 0; i < data.length; i++) {
                        if (data[i][this.key] === id) {
                            result = data[i];
                            break;
                        } else {
                            handle(id, data[i].children);
                        }
                    }
                }
            }
            handle(id);
            return result;
        }
        // 根据id找到对应节点的父节点
        findParentNode(id){
            const node = this.findNode(id);
            return node ? this.findNode(node[this.parentKey]) : null;
        }
        // 根据id找到对应节点所有的父节点
        findAllParentNode(id) {
            let result = [];
            const handle = (id) => {
                const parentNode = this.findParentNode(id);
                if (parentNode) {
                    result.push(parentNode);
                }
                if (parentNode && parentNode[this.parentKey] !== this.initial) {
                    handle(parentNode[this.key]);
                }
            }
            handle(id);
            return result;
        }
        // 根据id找到对应节点的子节点
        findChildrenNode(id) {
            const node = this.findNode(id);
            return node ? node.children : [];
        }
        // 根据id找到对应节点的路径
        findPath(id) {
            const node = this.findNode(id);
            const allParentNode = this.findAllParentNode(id);
            return node ? [node, ...allParentNode].reverse() : [];
        }
        // 根据id找到对应节点的叶子节点
        findLeafNode(id) {
            let result = []
            const handle = (id) => {
                const childrenNode = this.findChildrenNode(id);
                if (childrenNode.length) {
                    childrenNode.forEach(c => {
                        handle(c[this.key]);
                    })
                } else {
                    const node = this.findNode(id);
                    if (node) {
                        result.push(node);
                    }
                }
            }
            handle(id);
            return result;
        }
        // 获取树所有叶子节点
        findAllLeafNode() {
            let result = []
            this.data.forEach(c => {
                result.push(...this.findLeafNode(c[this.key]))
            });
            return result;
        }
        // 获取树的最大深度
        findMaxLevel() {
            let maxLevel = 0;
            this.findAllLeafNode().forEach(c => {
                const level = this.findPath(c[this.key]).length;
                if (level > maxLevel) {
                    maxLevel = level;
                }
            })
            return maxLevel;
        }
        // 遍历树--添加层级level和标记index
        setLevelIndex(data = this.data) {
            data.forEach((c, index) => {
                const level = this.findPath(c[this.key]).length;
                c.level = level;
                c.index = index;
                if (c.children.length) {
                    this.setLevelIndex(c.children);
                }
            })
        }
        // 找到指定level的所有节点
        findSameLevelNode(level) {
            let result = [];
            if ( level > this.findMaxLevel()) {
                return result;
            }
            const handle = (data = this.data) => {
                data.forEach(c => {
                    if (c.level === level) {
                        result.push(c);
                    } else {
                        if (c.children.length) {
                            handle(c.children)
                        }
                    }
                })
            }
            handle(this.data)
            return result;
        }

        // 对指定id的节点进行调整,会对树造成影响
        // setNode(id, obj = {}) {
        //    const node = this.findNode(id);
        //    const path =  this.findPath(id);
        //    const indexList = path.map(c => c.index);
        //    let str = `this.data[${indexList[0]}]`
        //    indexList.forEach((c, i) => {
        //        if (i > 0) {
        //            str += `.children[${c}]`
        //        }
        //
        //    })
        //    str += `=${JSON.stringify({...node, ...obj})}`
        //    return eval(str);
        // }

    }
	const list = [
        {
            id: '0-1', parentId: '0',name: '广东省',
        },
        {
            id: '0-2', parentId: '0',name: '湖南省',
        },
        {
            id: '0-3', parentId: '0',name: '湖北省',
        },
        {
            id: '0-4', parentId: '0',name: '江西省',
        },
        {
            id: '0-1-1', parentId: '0-1',name: '深圳',
        },
        {
            id: '0-1-2', parentId: '0-1',name: '广州',
        },
        {
            id: '0-1-3', parentId: '0-1',name: '汕头',
        },
        {
            id: '0-1-1-1', parentId: '0-1-1',name: '南山区',
        },
        {
            id: '0-1-1-1-1', parentId: '0-1-1-1',name: '粤海街道',
        },
        {
            id: '0-1-1-1-2', parentId: '0-1-1-1',name: '高新街道',
        },
        {
            id: '0-1-1-1-3', parentId: '0-1-1-1',name: '前海街道',
        },
        {
            id: '0-1-1-2', parentId: '0-1-1',name: '福田区',
        },
        {
            id: '0-1-1-3', parentId: '0-1-1',name: '宝安区',
        },
        {
            id: '0-1-2-1', parentId: '0-1-2',name: '天河区',
        },
        {
            id: '0-1-2-2', parentId: '0-1-2',name: '白云区',
        },
        {
            id: '0-1-3-1', parentId: '0-1-3',name: '潮阳区',
        },
        {
            id: '0-2-1', parentId: '0-2',name: '长沙',
        },
        {
            id: '0-2-2', parentId: '0-2',name: '益阳',
        },
        {
            id: '0-2-1-1', parentId: '0-2-1',name: '芙蓉区',
        },
        {
            id: '0-2-1-2', parentId: '0-2-1',name: '天心区',
        },
        {
            id: '0-2-2-1', parentId: '0-2-2',name: '赫山区',
        },
        {
            id: '0-3-1', parentId: '0-3',name: '武汉',
        },
        {
            id: '0-3-2', parentId: '0-3',name: '荆门',
        },
        {
            id: '0-3-3', parentId: '0-3',name: '黄石',
        },
        {
            id: '0-3-1-1', parentId: '0-3-1',name: '江汉区',
        },
        {
            id: '0-3-1-2', parentId: '0-3-1',name: '洪山区',
        },
        {
            id: '0-3-1-3', parentId: '0-3-1',name: '青山区',
        },
    ]
    const tree = new Tree({list, key: 'id', parentKey: 'parentId', initial: '0'});
    console.log('tree', tree)
    console.log(`${tree.findNode('0-1-1-1').name} => findNode => `, tree.findNode('0-1-1-1'));
    console.log(`${tree.findNode('0-1-1-1-2').name} => findParentNode => `, tree.findParentNode('0-1-1-1-2'));
    console.log(`${tree.findNode('0-1-1-1-2').name} => findParentsNode => `, tree.findAllParentNode('0-1-1-1-2'));
    console.log(`${tree.findNode('0-1-1-1').name} => findChildrenNode => `, tree.findChildrenNode('0-1-1-1'));
    console.log(`${tree.findNode('0-1-1-1-2').name} => findPath => `, tree.findPath('0-1-1-1-2'));
    console.log(`${tree.findNode('0-1').name} => findLeafNode => `, tree.findLeafNode('0-1'));
    console.log(`tree所有叶子节点 => findAllLeafNode => `, tree.findAllLeafNode());
    console.log(`tree最大深度 => findMaxLevel => `, tree.findMaxLevel());
    console.log(`level 2=> findSameLevelNode => `, tree.findSameLevelNode(3));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值