zoukankan      html  css  js  c++  java
  • 路径字符串数据转化为树型层级对象,path to json tree

    在参考文章 http://www.jb51.net/article/122967.htm 和 stackoverflow的一个路径转字符的回答 后,记录一下完成业务的代码.

    转化数组为带层级的数据其一

    由于项目中使用了react 及 ant-design ,在使用tree树型控件时,需要
    类似下面的数据,

    const treeData = [{
      title: '0-0',
      key: '0-0',
      children: [{
        title: '0-0-0',
        key: '0-0-0',
        children: [
          { title: '0-0-0-0', key: '0-0-0-0' },
          { title: '0-0-0-1', key: '0-0-0-1' },
          { title: '0-0-0-2', key: '0-0-0-2' },
        ],
      }];
    

    但是AWS传输过来的是下面这样的路径字符串数组,这就需要我们进行转化为树形层级对象了。

     var arr=[
        "root/",
        "root/a/",
        "root/a/new_b.png",
        "root/a/qa/",
        "root/a/qa/新建文本文档 (3).txt",
        "root/asdfasdfasdfasdfasdfasdfasdf.txt",
        "root/b.png",
        "root/instqj_gfzqhk.exe",
        "root/jupyter_notebook.png",
        "root/new_b.png",
        "root/output/new_b.png",
        "root/soffice.exe",
        "root/ti/asdfasdfasdfasdfasdfasdfasdf.txt",
        "root/watermark.zip",
        "root/中华人民共和国国民经济和社会发展 第十三个五年规划纲要 .pdf",
        "root/国务院发布《中国制造2025》%28全文%29.pdf",
        "root/新建文本文档 (3).txt",
        "root/新建文本文档.txt",
        "root/沧海一声笑.docx",
        "root/理光C2011SP.exe"
    ]
    
    

    接下来我们开始行动

    转化数组为带层级的数据

    
    const pathToTree = (input) => {
      let root = [];
      for (let i=0;i<input.length;i++){
        let chain = input[i].split("/");
        let currentHierarchy = root;
        for(let j = 0; j < chain.length;j++){
          let wantedNode = chain[j]
          if(wantedNode === ''){
            continue;
          }
          let lastHierarchy = currentHierarchy;
    
          // 遍历root是否已有该层级
          for(let k = 0; k < currentHierarchy.length;k++){
            if(currentHierarchy[k].title === wantedNode){
              currentHierarchy = currentHierarchy[k].children;
              break;
            }
          }
    
          if(lastHierarchy === currentHierarchy) {
            let key;
            if(j === chain.length - 1){
              key = input[i];
            } else {
              key = chain.slice(0,j+1).join('/')+'/';
            }
            let newNode = {
              key: key,
              title: wantedNode,
              children: []
            };
            // 文件,最后一个字符不是"/“符号
            if(j=== chain.length-1){
              delete newNode.children;
            }
            currentHierarchy.push(newNode);
            currentHierarchy = newNode.children;
          }
        }
      }
    
      return root;
    }
    
    
    console.log(pathToTree(arr))
    

    得到了我们想要的结果

    遍历树节点

    光是这样还不够,我们使用ant-design中的tree树形控件,不能让最低层级有children属性,同时,我们自己也可以额外定一个需求:所有文件名字长度不能超过一定数量。
    另外,由于我的项目是上传到亚马逊S3,有的文件夹不会返回给我,比如这个文件"root/ti/asdfasdfasdfasdfasdfasdfasdf.txt"就没有返回" root/ti/",所以我们要加上个层级数据,不能有相同的key。
    我们这里遍历这个树型对象。中文和英文字符宽度不一样,一般需要区分一样,这里就简单处理一下。

    const traverseTree = function (data) {
        return data.map((item) => {
            //如果有相同的key,react的渲染会有问题,所以要处理一下。
            let chain = item.key.split('/');
            if (item.title !== chain.slice(-1)[0]) {
                item.key = chain.slice(0, -1).join('/')
            }
            item.title = item.title.length > 10 ? item.title.substring(0, 7) + "..." : item.title
            if (item.children.length > 0) {
                traverseTree(item.children)
                return item
    
            } else {
                delete item.children
                return item
            }
        })
    }
    
    console.log(traverseTree(pathToTree(arr)))
    

    输出结果

    转化数组为带层级的数据其二

    当然有时候,后台传给我吗的数据是这样用pid记录位置的。

    var data = [
     {"id":2,"name":"第一级1","pid":0},
     {"id":3,"name":"第二级1","pid":2},
     {"id":5,"name":"第三级1","pid":4},
     {"id":100,"name":"第三级2","pid":3},
     {"id":6,"name":"第三级2","pid":3},
     {"id":601,"name":"第三级2","pid":6},
     {"id":602,"name":"第三级2","pid":6},
     {"id":603,"name":"第三级2","pid":6}
    ];
    

    我们就用这个函数进行转化树状层级结构

    function arrayToJson(treeArray) {
        var r = [];
        var tmpMap = {};
    
        for (var i = 0, l = treeArray.length; i < l; i++) {
            // 以每条数据的id作为obj的key值,数据作为value值存入到一个临时对象里面
            tmpMap[treeArray[i]["id"]] = treeArray[i];
        }
    
        for (i = 0, l = treeArray.length; i < l; i++) {
            var key = tmpMap[treeArray[i]["pid"]];
    
            //循环每一条数据的pid,假如这个临时对象有这个key值,就代表这个key对应的数据有children,需要Push进去
            if (key) {
                if (!key["children"]) {
                    key["children"] = [];
                    key["children"].push(treeArray[i]);
                } else {
                    key["children"].push(treeArray[i]);
                }
            } else {
                //如果没有这个Key值,那就代表没有父级,直接放在最外层
                r.push(treeArray[i]);
            }
        }
        return r
    }
    

    树形组件搜索功能

    树形组件经常带搜索功能。前端一般使用数组的filter方法就满足要求了。
    如果数组有层级结构,就转化为没有层级结构的数组。然后再filter就可以了。

    var jsonToArray = function (nodes) {
      var r = [];
      if (Array.isArray(nodes)) {
        for (var i = 0, l = nodes.length; i < l; i++) {
          r.push(nodes[i]);
          if (Array.isArray(nodes[i]["children"]) && nodes[i]["children"].length > 0)
            //将children递归的push到最外层的数组r里面
            r = r.concat(jsonToArray(nodes[i]["children"]));
          delete nodes[i]["children"]
        }
      }
      return r;
    }
    
  • 相关阅读:
    Django---Blog系统开发之注册页面(验证码&ajax发送文件)
    Django---Blog系统开发之建库
    Eclipse下导入外部jar包的3种方式
    linux 下 .sh 文件语法
    热备,冷备,云备的区别
    plsql 中如何清除曾经登录过的用户名
    Mac 查看python安装路径
    mac terminal终端怎么退出python命令行
    PyCharm 2017 Mac 免注册版破解安装说明
    PL/SQL恢复默认窗口样式
  • 原文地址:https://www.cnblogs.com/liaozhenting/p/8343827.html
Copyright © 2011-2022 走看看