一维数组结构数据转换树形结构数据JS方法

在写小程序项目时,自定义了一个组织机构树形展示组件,后端接口返回的组织机构数据是一维数组。需要在前端转换成树形结构的数据,并且添加一些节点的树形,比如是否为叶子节点,节点是否展开等,在自定义的组件中通过这些属性,做出友好的用户交互效果。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script>
      var arr = [
        { id: 0, pid: null, text: "父级" },
        { id: 1, pid: 0, text: "一级1" },
        { id: 2, pid: 0, text: "一级2" },
        { id: 3, pid: 1, text: "二级1-1" },
        { id: 4, pid: 1, text: "二级1-2" },
        { id: 5, pid: 2, text: "二级2-1" },
        { id: 6, pid: 2, text: "二级2-2" },
        { id: 7, pid: 3, text: "三级1-1-1" },
        { id: 8, pid: 7, text: "四级1-1-1-1" },
        { id: 9, pid: 8, text: "五级1-1-1-1-1" },
        { id: 10, pid: 9, text: "六级1-1-1-1-1" },
      ];
      let arrayToTree = function (dataArr, rootId) {
        let arr = JSON.parse(JSON.stringify(dataArr));
        // 获取所有顶级分类,然后组成数组
        let parents = arr.filter((v) => v.pid === rootId);
        // 获取所有非顶级分类,组成数组
        let children = arr.filter((v) => v.pid !== rootId);
        // 定义递归方法, 传入参数,父级数组,和子集数组
        function dataToTree(p, c) {
          // 循环遍历父级数组
          p.forEach((p_v) => {
            // 循环遍历子集数组
            p_v.isOpen = false;
            c.forEach((c_v, c_i) => {
              // 判断当前的子项是否为当前的父项的子元素
              if (c_v.pid === p_v.id) {
                // 如果是那么判断当前,当前父类项是否有children 字段
                if (!p_v.children) {
                  // 如果没有初始化为空数组
                  p_v.children = [];
                  c_v.isLeaf = true;
                }
                // 然后把当前的子类项推到父类的children数组中
                p_v.children.push(c_v);
                // 在执行递归调用当前方法,把当前子类项以数组的形式作为第一个参数传入,然后把所有的子集数组作为第二个参数传入,从新遍历所有子类数组中是否有当前子类的下一级
                // dataToTree([c_v], children);
                p_v.isLeaf = false;
                c_v.isLeaf = true;
                /* 为了减少遍历的次数可以把当前项从子类型中删除 */
                // 然后把所有的子集数组深拷贝一份,因为数组中的项是对象属于引用类型的
                let _c = JSON.parse(JSON.stringify(c));
                //然后把当前子类项从整体的子类数组中剔除
                _c.splice(c_i, 1);
                // 在执行递归调用当前方法,把当前子类项以数组的形式作为第一个参数传入,然后把所有的子集数组作为第二个参数传入,从新遍历所有子类数组中是否有当前子类的下一级
                dataToTree([c_v], _c);
              }
              c_v.isOpen = false;
            });
          });
        }
        dataToTree(parents, children);
        return parents;
      };
      let getTree = arrayToTree(arr, null);
      console.log(getTree);
    </script>
  </head>
  <body></body>
</html>

原创文章,作者:ZERO,如若转载,请注明出处:https://www.edu24.cn/course/array-to-tree-js.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
ZEROZERO
上一篇 2022年11月9日
下一篇 2022年11月10日

相关推荐

  • 封装JDBC工具类,连接MySQL数据库

    JDBC是由java编程语言编写的类及接口组成,同时它为程序开发人员提供了一组用于实现对数据库访问的JDBC API,并支持SQL语言。利用JDBC可以将JAVA代码连接到orac…

    2022年3月31日
    1.0K
  • Java自学之继承

    在面向对象的设计过程中,类是基本的逻辑单位。但是对于这些基本的逻辑单位需要考虑到重用的设计问题,所以在面向对象的设计里提供有继承,并利用这一特点实现类的可重用性定义。 类继承定义 …

    2020年12月3日
    1.6K
  • Webpack入门,预处理器

    一个Web工程通常会包含HTML、JS、CSS、图片、字体等多种类型的静态资源,且这些资源之间都存在着某种联系。对于Webpack来说,所有这些静态资源都是模块,开发者可以像加载一…

    2022年11月21日
    880
  • Angular4.x ngModel 指令详解

    用过angular的前端工程师都知道,angular数据是可以双向绑定的。但是它为什么可以使数据双向绑定?原理又是什么?阅读这篇文章,来了解一下吧。

    2019年7月3日
    2.1K
  • windows 11 如何安装Docker Desktop

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化…

    2022年10月27日
    634
  • Webpack入门,模块打包之加载其他类型的模块

    在实际开发中,开发者可能遇到其他类型的模块,比如AMD、UMD模块,虽然这些模块在目前的使用场景已经不多,但是遇到这些模块时仍然需要知道如何处理。 加载非模块化的文件 非模块化文件…

    2022年11月14日
    801
  • spring4.x学习之创建工程

    断断续续学习Java有两三个月了,目前还是处于入门阶段。关于java及spring那些的设计理念方面的理论知识,不花费大量精力及时间是看不懂的(至少对于我这么一个前端转后端的初学者…

    2019年3月19日
    2.0K
  • Angular环境搭建(Windows 10)

    目前前端开发正处于快速发展阶段,接触angular时,Angular 2刚刚发布,现在第五版也已经发布。由于刚开始没有系统的学习,导致工作中,经常捉襟见肘。现在把自己在工作中踩过的…

    2018年9月5日
    4.3K
  • Java自学之多线程编程

    多线程编程是Java语言最为重要的特性之一。利用多线程技术可以提升单位时间内的程序处理性能,也是现代程序开发中高并发的主要设计模式。 进程与线程 进程是一个应用程序。线程是一个进程…

    2020年12月16日
    1.7K
  • 如何使用IDEA2020.2新建servlet工程

    最近自学java时,发现IDEA更新到2020.2版本时,在新建工程时,有了明显的改动。由于小编刚学到servlet,IDEA这一突然间的改动,导致小编不会新建servlet工程了…

    2020年8月17日
    6.1K