路径字符串数据转化为树型层级对象,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;
}
路径字符串数据转化为树型层级对象,path to json tree的更多相关文章
- PyQt(Python+Qt)学习随笔:QTreeWidgetItem项的子项排序sortChildren及获取项对应的树型部件对象方法
		老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 1.sortChildren对子项排序 树型部件QTreeWidget中的QTreeWidgetIt ... 
- R语言将字符串矩阵转化为数值型矩阵
		这是原始数据的格式,当运行完下面的命令的时候,结果如下图 x=read.table("C:/Users/Administrator/Desktop/s1.txt") x=as.ma ... 
- 树型权限管理插件:jQuery Tree Multiselect详细使用指南
		1.认识jQuery Tree Multiselect 这个插件允许用户以树型的形式来呈现列表复选框的选择.多用于权限管理中用于分配不同的权限.使用文档,请参考: https://github ... 
- [JavaScript] 将字符串数组转化为整型数组
		var dataStr="1,2,3,4,5";//原始字符串 var dataStrArr=dataStr.split(",");//分割成字符串数组 var ... 
- python中字符串list转化为数值型
		之前在网上找相关的资料,给出的方法都不合适, 经过很长时间的试错才知道源于python2.X和python3.X的不同, 原理都是采用map函数,但是二者返回的信息不同 Python2.x,可以使用m ... 
- 树型结构递归 实体递归 JSON格式
		用递归实现无限级菜单,产品分类,盖楼式评论.留言等功能. 下列代码不能直接使用 CREATE TABLE [dbo].[P_Category]( [Code] [varchar](36) NOT NU ... 
- 将数据转换成树型层级的Json格式的String
		有时候我们项目里面需要将树型关系的数据转换成Json格式的String字符串 假设数据库中的数据如下 需要转换后输出的字符串的结果如下(对应的层级的关系) [ {name:'爷爷',id:'1',co ... 
- js中把ajax获取的数据转化成树状结构(并做成多级联动效果)
		1.首先通过ajax获取数据,此处省略,直接贴出获取到的数据格式 var arr = [{ id: 1, name: "一级标题", pid: 0 }, { id: 2, name ... 
- WPF 4 目录树型显示
		原文:WPF 4 目录树型显示 本篇将通过WPF4 制作简单的目录树型结构显示实例,完成本篇内容我们将作出下图所示的应用程序. 从图中我们可以看到程序主要分为两部分:左边显示本地驱 ... 
随机推荐
- JSP路径出现问题
			1.错误描述 2.错误原因 <%@ page language="java" import="java.util.*" pageEncoding=&quo ... 
- hibernate学习(三) hibernate中的对象状态
			hibernate对象的状态分为三种: 游离状态,持久化状态,瞬时状态 下面一行代码区分: Configuration cfg=new Configuration().configure(); ... 
- javaWeb事务
			JDBC事务: cmd 命令上的事务开启: start transaction; / begin; 回滚 rollback; 提交 commit; JDBC事务控制: 开启事务:co ... 
- ACM1008
			题目:Haab日历和Tzolkin日历的转换. Maya一共有两种日历,第一种日历名为Haab,将一年分为365天,一共有19个月.其中前18个月,分别命名为pop.nozip.zotz.tzec.x ... 
- Query 插件为什么要return this.each()
			jQuery.fn.test2= function(){ this.css("background","#ff0");//这里面的this为jquery对象,而 ... 
- 异常-----freemarker.template.TemplateException:Error executing macro:mainSelect
			1.错误描述 freemarker.template.TemplateException:Error executing macro:mainSelect require parameter:id i ... 
- CSS3 2D、3D转换
			2D转换方法:transform().rotate().scale().skew().matrix() 3D转换方法:rotateX().rotateY() 1.示例代码 <!DOCTYPE h ... 
- 分享到JavaScript
			<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ... 
- 【洛谷1129】 [ZJOI2007]矩阵游戏
			题面 题目描述 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏.矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作: ... 
- [BZOJ1503] [NOI2004] 郁闷的出纳员 (treap)
			Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ... 
