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;
    }
    
  • 相关阅读:
    MQTT TLS 加密传输
    python多进程并发redis
    各种消息队列的特点
    mqtt异步publish方法
    Numpy API Analysis
    Karma install steps for unit test of Angular JS app
    reinstall bower command
    Simulate getter in JavaScript by valueOf and toString method
    How to: Raise and Consume Events
    获取对象的类型信息 (JavaScript)
  • 原文地址:https://www.cnblogs.com/liaozhenting/p/8343827.html
Copyright © 2011-2022 走看看