工具函数:普通数组如何转为树形结构数据(多层级)数组?

前言

最近一直在做的是一个后台管理系统,更偏向于对数据的一个处理.其中最典型的数据处理,就是树形结构数据,比如用在侧边栏菜单,比如去描述各部门之间的上下级关系等等.有的时候后端勤快一点,把它处理了,但是万一没有呢?那就需要前端去处理喽!另外补一句:坑爹的win10系统,又浪费了朕半天时间去重新配置环境.

第一种方案

技术点:面向对象,递归函数

可以用json-server插件去简单搭建一个服务器,提供数据支撑

代码如下:(基于vue技术栈,iview-ui框架的tree组件的一个工具函数)

// 该模块用于将普通数组去转化为树形结构的数组结构
// 导出一个构造函数,所以在使用的时候,要new一个对象
export function TreeData (a) {
  // 若a为空,tree即为空数组,否则即为获取的数组数据
  this.tree = a || [];
  this.groups = {};
}
TreeData.prototype = {
  init: function (parentid) {
    // parentid的值在组件中被定义为0
    this.group();
    // 此时this.groups每一个parentid也只有一个子元素
    return this.getDom(this.groups[parentid]);
  },
  group: function () {
    // 该函数将普通数组处理成二级结构,属性名为父部门id,属性值为子部门的部门信息(数据形式为对象)
    // 每一个拥有子部门的父部门id都将作为this.groups的属性名
    for (var i = 0; i < this.tree.length; i++) {
      if (this.groups[this.tree[i].parentid]) {
        // 目前数据中每一个部门的部门信息中parentid都是存在的,写一个if分歧应该是为了防止后端数据的失误
        // 父级已经存在,使得同一级的子级能够被追加进去
        this.groups[this.tree[i].parentid].push(this.tree[i]);
      } else {
        // 数组元素的parentid值去做了groups的属性名,parentid实际上是数字呀,就是要将子集数据追加到父集
        // this.groups对象是没有属性的,所有的parentid都将作为this.groups的属性值
        this.groups[this.tree[i].parentid] = [];
        this.groups[this.tree[i].parentid].push(this.tree[i]);
      }
    }
  },
  // 非常任性,使用了函数递归,手法近似于深拷贝,对象才能一层一层的放下去
  getDom: function (a) {
    // a即为this.groups的属性对象,如果不存在就返回为空,即后台返回的数据为空的时候
    if (!a) {
      return '';
    }
    // 重新拼接出了一个JSON字符串,所需要的树形数据结构的字符串形式,且有序排列
    // this.groups仅仅提供了一个拥有两个层级的数据结构
    var data = '[';
    for (let i = 0; i < a.length; i++) {
      // this.groups[parentid]里面的对象在group函数中被有序追加
      // "expand":"true","type":"department"的添加是出于iview的tree控件和项目其他地方的需要
      data += `{"title":"${a[i].departmentname}","departmentid":"${a[i].departmentid}","parentid":"${a[i].parentid}","expand":"true","type":"department"`;
      // 以第一次进入该函数为例
      // 因为有parentid为0的存在,所以部门里我更愿意增加一个0级部门
      // 如果一级部门还有子部门,就接着拼接children属性值
      data += this.getDom(this.groups[a[i].departmentid]) ? ',' : '';
      // 将二级部门追加到一级部门的children属性中
      data += this.getDom(this.groups[a[i].departmentid]) ? '"children":' + this.getDom(this.groups[a[i].departmentid]) : '';
      if (i === a.length - 1) {
        // 同层级的数据被添加完成
        data += '}';
      } else {
        data += '},';
      }
    };
    data += ']';
    return data;
  }
};
复制代码

要处理的数据:

{
  "msg": "success",
  "code": 200,
  "data": [
    {
      "departmentid": 1,
      "departmentname": "总部",
      "parentid": 0,
      "isrmv": false,
      "sort": 1,
      "leaderid": null,
      "qxDepartmentid": 1
    },
    {
      "departmentid": 2,
      "departmentname": "总经办",
      "parentid": 1,
      "isrmv": false,
      "sort": 1,
      "leaderid": 44220,
      "qxDepartmentid": null
    },
    {
      "departmentid": 4,
      "departmentname": "IT部",
      "parentid": 1,
      "isrmv": false,
      "sort": 3,
      "leaderid": null,
      "qxDepartmentid": null
    },
    {
      "departmentid": 9,
      "departmentname": "技术组",
      "parentid": 1,
      "isrmv": false,
      "sort": null,
      "leaderid": null,
      "qxDepartmentid": 1432010565
    },
    {
      "departmentid": 10,
      "departmentname": "财务部",
      "parentid": 1,
      "isrmv": false,
      "sort": null,
      "leaderid": null,
      "qxDepartmentid": 1432014225
    },
    {
      "departmentid": 28,
      "departmentname": "总经办22",
      "parentid": 1,
      "isrmv": false,
      "sort": null,
      "leaderid": null,
      "qxDepartmentid": null
    },
    {
      "departmentid": 31,
      "departmentname": "技术组1",
      "parentid": 4,
      "isrmv": false,
      "sort": null,
      "leaderid": null,
      "qxDepartmentid": null
    },
    {
      "departmentid": 32,
      "departmentname": "啦啦",
      "parentid": 4,
      "isrmv": false,
      "sort": null,
      "leaderid": null,
      "qxDepartmentid": null
    },
    {
      "departmentid": 33,
      "departmentname": "test23",
      "parentid": 1,
      "isrmv": false,
      "sort": null,
      "leaderid": null,
      "qxDepartmentid": 33
    },
    {
      "departmentid": 38,
      "departmentname": "测试部门3",
      "parentid": 1,
      "isrmv": false,
      "sort": null,
      "leaderid": 44229,
      "qxDepartmentid": 1432014228
    },
    {
      "departmentid": 39,
      "departmentname": "测试部门31",
      "parentid": 38,
      "isrmv": false,
      "sort": null,
      "leaderid": 44283,
      "qxDepartmentid": 1432014229
    },
    {
      "departmentid": 40,
      "departmentname": "测试部门32",
      "parentid": 38,
      "isrmv": false,
      "sort": null,
      "leaderid": 44246,
      "qxDepartmentid": 1432014230
    },
    {
      "departmentid": 41,
      "departmentname": "测试部门311",
      "parentid": 39,
      "isrmv": false,
      "sort": null,
      "leaderid": 44239,
      "qxDepartmentid": 1432014231
    },
    {
      "departmentid": 44,
      "departmentname": "测试部门34",
      "parentid": 38,
      "isrmv": false,
      "sort": null,
      "leaderid": null,
      "qxDepartmentid": 1432014233
    }
  ]
}
复制代码

处理后的数据:(expand是iview-ui的tree组件决定节点是否展开的一个字段)


[
    {
        "children": [
            {
                "children": [],
                "departmentid": "2",
                "expand": "true",
                "parentid": "1",
                "title": "总经办",
                "type": "department"
            },
            {
                "children": [
                    {
                        "departmentid": "31",
                        "expand": "true",
                        "parentid": "4",
                        "title": "技术组1",
                        "type": "department"
                    },
                    {
                        "departmentid": "32",
                        "expand": "true",
                        "parentid": "4",
                        "title": "啦啦",
                        "type": "department"
                    }
                ],
                "departmentid": "4",
                "expand": "true",
                "parentid": "1",
                "title": "IT部",
                "type": "department"
            },
            {
                "departmentid": "9",
                "expand": "true",
                "parentid": "1",
                "title": "技术组",
                "type": "department"
            },
            {
                "departmentid": "10",
                "expand": "true",
                "parentid": "1",
                "title": "财务部",
                "type": "department"
            },
            {
                "departmentid": "28",
                "expand": "true",
                "parentid": "1",
                "title": "总经办22",
                "type": "department"
            },
            {
                "departmentid": "33",
                "expand": "true",
                "parentid": "1",
                "title": "test23",
                "type": "department"
            },
            {
                "children": [
                    {
                        "children": [
                            {
                                "departmentid": "41",
                                "expand": "true",
                                "parentid": "39",
                                "title": "测试部门311",
                                "type": "department"
                            }
                        ],
                        "departmentid": "39",
                        "expand": "true",
                        "parentid": "38",
                        "title": "测试部门31",
                        "type": "department"
                    },
                    {
                        "departmentid": "40",
                        "expand": "true",
                        "parentid": "38",
                        "title": "测试部门32",
                        "type": "department"
                    },
                    {
                        "departmentid": "44",
                        "expand": "true",
                        "parentid": "38",
                        "title": "测试部门34",
                        "type": "department"
                    }
                ],
                "departmentid": "38",
                "expand": "true",
                "parentid": "1",
                "title": "测试部门3",
                "type": "department"
            }
        ],
        "departmentid": "1",
        "expand": "true",
        "parentid": "0",
        "title": "总部",
        "type": "department"
    }
]
复制代码

最终的效果图

第二种方案

关键字 id,parentId ,child

判断是root节点的方法为 parentId===0

        let data = [
        {id: 1, text: 't11', parentId: 0},
        {id: 2, text: 't11', parentId: 0},
        {id: 3, text: 't11', parentId: 1},
        {id: 4, text: 't11', parentId: 1},
        {id: 5, text: 't11', parentId: 3},
        {id: 6, text: 't11', parentId: 2},
        ];
        data.forEach(ele => {
            // 第一次forEach遍历到所有的数组对象,不做去重,数组依旧拥有6个元素
        let parentId = ele.parentId;
        if (parentId === 0) {
            //是根元素的hua ,不做任何操作,如果是正常的for-i循环,可以直接continue.
        } else {
            //如果ele是子元素的话 ,把ele扔到他的父亲的child数组中.它的父元素也可能是别人的子元素
            //遍历6遍,数组依旧拥有6个元素,只不过有些有嵌套关系
            data.forEach(d => {
            if (d.id === parentId) {
                let childArray = d.child;
                // 一则避免了去给d.child声明定义空数组
                // childArray为undefined时,用push方法去报undefined.push的错
                if (!childArray) {
                    childArray = []
                }
                // 用push保证同级别的对象有序追加
                childArray.push(ele);
                d.child = childArray;
            } //else的地方不做处理,保证了最深层的对象没有child属性
            })
        }
        });
        //去除重复元素
        data = data.filter(ele => ele.parentId === 0);
        console.log('最终等到的tree结构数据: ', data);
复制代码

你可能感兴趣的:(工具函数:普通数组如何转为树形结构数据(多层级)数组?)