浅理解扁平数据结构转Tree(树形结构)

Posted 黛琳ghz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅理解扁平数据结构转Tree(树形结构)相关的知识,希望对你有一定的参考价值。

文章目录


📋前言

在前端开发中,我们经常需要将扁平数据结构转换为树形结构(Tree)。比如在网站菜单、商品分类等场景下,都需要使用树形结构来实现数据的层级呈现。在本篇博客中,我将介绍一种常见的方法,使用递归方式来将扁平数据结构转换成树形结构。


🎯扁平数据结构

扁平数据结构是指数据之间没有任何层次关系,每个数据项都是平级的,通常包含一个parentId字段来表示该数据项的父节点。这种数据结构通常被用于列表、表格等场景下,但对于层级结构的数据展示则不够方便。

例如,以下是一个扁平数据结构的示例:

const flatData = [
   id: 1, name: '节点1', parentId: null ,
   id: 2, name: '节点2', parentId: 1 ,
   id: 3, name: '节点3', parentId: 1 ,
   id: 4, name: '节点4', parentId: 2 ,
   id: 5, name: '节点5', parentId: 2 ,
   id: 6, name: '节点6', parentId: 3 
];

🎯树形数据结构

而树形数据结构则是一种具有层次结构的数据结构,在前端开发中通常用于展示层级结构的数据,如文件夹、分类、组织架构等。每个节点仅有一个父节点,但可以有任意多个子节点

以下是一个树形数据结构的示例:

const treeData = [
  
    id: 1,
    name: '节点1',
    children: [
      
        id: 2,
        name: '节点2',
        children: [
           id: 4, name: '节点4' ,
           id: 5, name: '节点5' 
        ]
      ,
      
        id: 3,
        name: '节点3',
        children: [
           id: 6, name: '节点6' 
        ]
      
    ]
  
];

🎯使用递归将扁平数据转换为树形数据

在前面的示例中,我们看到扁平数据结构与树形数据结构之间存在一定的转换关系,我们可以通过递归的方式将扁平数据结构转换为树形数据结构。

以下是一个使用递归的方法实现这个过程的代码示例:

function flatToTree(flatData, parentId = null) 
  const tree = [];
  
  // 遍历flatData,找到parentId对应的子节点
  for (const node of flatData) 
    if (node.parentId === parentId) 
      // 递归查找子节点
      const children = flatToTree(flatData, node.id);
      
      // 如果有子节点,则加入children属性中
      if (children.length > 0) 
        node.children = children;
      
      
      // 加入tree中
      tree.push(node);
    
  
  
  return tree;


const treeData = flatToTree(flatData);
console.log(treeData); // 输出转换得到的Tree数据


以上代码使用递归的方式将扁平数据结构转换为树形数据结构。其中,flatToTree函数接收两个参数:flatData表示要转换的扁平数据结构,parentId是当前处理节点的父节点ID(初始值为null)。函数返回一个数组,包含所有根节点。

在函数体内,通过遍历flatData,找到所有parentId等于当前节点id的子节点。对每个子节点,再使用递归调用flatToTree函数查找该节点的子节点,并将子节点添加到children属性中。最终将所有节点加入到tree数组中并返回。


📝最后

通过以上的内容,我们可以浅理解如何使用递归的方式将扁平数据结构转换成树形数据结构。这是一种常见的实现方法,但在数据量较大时可能会影响性能,可以考虑使用其他的实现方式。当然,对于小规模的数据转换,递归是非常方便和好理解的。

js把树形数据转成扁平数据

我就直接上代码了都是实际项目里面用到的

1.假设这个json就已经是树型结构数据了(如果不知道怎么实现树型结构数据请看我另一篇博客
var compressedArr=afcommon.treeDataToCompressed(json);

/*******************************JS封装好的方法*********************************************/

var afcommon=(function ($) {
var prefix="|—";
let compressedData=[];// 用于存储递归结果(扁平数据)
return {

/**
* 把扁平数据转成树型结构数据(可以实现无限层级树形数据结构,只适用于单个表的数据)
* @param source
* @param id
* @param parentId
* @param children
*/
treeDataformat : function(source, id, parentId, children){
let cloneData = JSON.parse(JSON.stringify(source)); // 对源数据深度克隆
return cloneData.filter(father=>{ // 循环所有项,并添加children属性
let branchArr = cloneData.filter(child => father[id] == child[parentId]); // 返回每一项的子级数组
branchArr.length>0 ? father[children] = branchArr : \'\' //给父级添加一个children属性,并赋值
return father[parentId] == 0 // 如果第一层不是parentId=0,请自行修改
})
},
/**
* 把树型结构数据转成扁平数据(跟treeDataformat方法相反)
* @param source
*/
treeDataToCompressed :function (source) {
for(let i in source) {
compressedData.push(source[i]);
source[i].children && source[i].children.length>0 ? this.treeDataToCompressed(source[i].children) : ""// 子级递归
}
return compressedData;
},
/**
* 递归生成 树下拉菜单
* @param JsonTree 此参数已经是树型结构的数据了 如:JsonTree[{"id": "0","value":"测试","children": []}]
* @param typeId
* @param name
* @returns {string}
*/
creatSelectTree : function(JsonTree,typeId,name){//js脚本,递归生成 树下拉菜单
var option="";
for(var i=0;i<JsonTree.length;i++){
if(JsonTree[i].children!= undefined && JsonTree[i].children.length>0){//如果有子集
option+="<option value=\'"+JsonTree[i][typeId]+"\'>"+prefix+JsonTree[i][name]+"</option>";
prefix+="|—";//前缀符号加一个符号
option+=this.creatSelectTree(JsonTree[i].children,typeId,name);//递归调用子集
prefix=prefix.slice(0,prefix.length-2);//每次递归结束返回上级时,前缀符号需要减一个符号
}else{//没有子集直接显示
option+="<option value=\'"+JsonTree[i][typeId]+"\'>"+prefix+JsonTree[i][name]+"</option>";
}
}
return option;//返回最终html结果
},
/**
* 适用于layer.confirm 动态改变title 多语言切换
* layer.confirm(msg,{titel:\'Message\'},{btn: [\'确定\',\'取消\']}, function () {},function () {}) (这样写改变title 好像会对后面的回调函数有影响,不信你试试)
* @param title
* @param index
*/
changeLayerTitle: function (title,index) {
return layer.title(title, index)
},
}
})(jQuery);

测试结构:

好的东西就要懂得分享,推荐一个写的好的博客一个字来形容———厉害!

https://blog.csdn.net/Mr_JavaScript/article/details/102833991

以上是关于浅理解扁平数据结构转Tree(树形结构)的主要内容,如果未能解决你的问题,请参考以下文章

js把树形数据转成扁平数据

树形数据结构和扁平数据相互转换

JavaScript 扁平与树形数组数据的转换

Javascript中扁平化数据结构与JSON树形结构转换详解

什么是网站结构扁平化及树状结构

什么是网站的扁平结构与树形结构