把有层级的一维数组改为树形结构

Posted eyan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了把有层级的一维数组改为树形结构相关的知识,希望对你有一定的参考价值。

朋友问的问题,我试着写了一下。用了两层递归,感觉很麻烦。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
</html>
    
<script type="text/javascript">
    
let tree =[
    
        id: 2,
        name: "节点二",
        parentId: null
    ,
    
        id: 9,
        name: "节点1-1",
        parentId: 1
    ,
    
        id: 19,
        name: "节点1-2",
        parentId: 1
    ,
    
        id: 39,
        name: "节点三",
        parentId: null
    ,
    
        id: 40,
        name: "节点1-3",
        parentId: 1
    ,
    
        id: 41,
        name: "节点1-1-1",
        parentId: 9
    ,
    
        id: 1,
        name: "节点一",
        parentId: null
    ,
]

let newArr=[];
for(let i=0;i<tree.length;i++)
    tree[i].children=[];//先向所有节点添加子节点

function makeTree()
    const treeCopy=JSON.parse(JSON.stringify(tree));//每次递归拷贝一份原始数据,用于循环变量i;
    for(let i=0;i<treeCopy.length;i++)
        if(treeCopy[i].parentId)//判断根节点
            const tr=this.compare(treeCopy[i],newArr);
            if(tr)
                tree=tree.filter(item=>//将已匹配的子节点剔除数组
                    return item.id!==tr.id
                );
            
        else
            newArr.push(treeCopy[i]);
            tree=tree.filter(item=>//将根节点剔除数组
                return item.id!==treeCopy[i].id
            );
        
    
    if(tree.length)//原始数组剔除完递归结束
        this.makeTree();
    

function compare(t,nArr)
    for(let j =0;j<nArr.length;j++)
        if(nArr[j].id===t.parentId)//先比较当前节点
            nArr[j].children.push(t);
            return t;
        
        if(nArr[j].children.length)//当前节点匹配不上匹配子节点
            return this.compare(t,nArr[j].children);
        
    
    return false;

this.makeTree();
console.log(newArr);

</script>

朋友的朋友也拿去实现了一下,我瞬间感觉自己弱爆了。。。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
</html>
    
<script type="text/javascript">
    
let arr =[
    
        id: 41,
        name: "节点1-1-1",
        parentId: 9
    ,
    
        id: 2,
        name: "节点二",
        parentId: null
    ,
    
        id: 9,
        name: "节点1-1",
        parentId: 1
    ,
    
        id: 19,
        name: "节点1-2",
        parentId: 1
    ,
    
        id: 39,
        name: "节点三",
        parentId: null
    ,
    
        id: 40,
        name: "节点1-3",
        parentId: 1
    ,
    
        id: 1,
        name: "节点一",
        parentId: null
    ,
    
        id: 55,
        name: "节点1-1-1-1",
        parentId: 41
    ,
]

var data = [...arr];
var tree = data.filter((father) => 
  var branchArr = data.filter((child) => 
    if (father.id == child.parentId ) child._hasParent = true;
    return father.id == child.parentId;
  );
  if (branchArr.length > 0) father.children = branchArr;
  return !father._hasParent;
);
tree = tree.filter((item) => 
  return !item._hasParent;
)

</script>

思路已经比较清楚了,可是代码理着理着就乱了,果然还是自己会的东西太少了吧,还是得多看多学。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
</html>
    
<script type="text/javascript">
    
let tree =[
 
id: 2,
name: "节点二",
parentId: null
,
id: 9,
name: "节点1-1",
parentId: 1
,
id: 19,
name: "节点1-2",
parentId: 1
,
id: 39,
name: "节点三",
parentId: null
,
id: 40,
name: "节点1-3",
parentId: 1
,
id: 41,
name: "节点1-1-1",
parentId: 9
,
id: 1,
name: "节点一",
parentId: null
,
]

let newArr=[];
for(let i=0;i<tree.length;i++)
tree[i].children=[];//先向所有节点添加子节点
function makeTree()
const treeCopy=JSON.parse(JSON.stringify(tree));//每次递归拷贝一份原始数据,用于循环变量i;
for(let i=0;i<treeCopy.length;i++)
if(treeCopy[i].parentId)//判断根节点
const tr=this.compare(treeCopy[i],newArr);
if(tr)
tree=tree.filter(item=>//将已匹配的子节点剔除数组
return item.id!==tr.id
);
else
newArr.push(treeCopy[i]);
tree=tree.filter(item=>//将根节点剔除数组
return item.id!==treeCopy[i].id
);
if(tree.length)//原始数组剔除完递归结束
this.makeTree();
function compare(t,nArr)
for(let j =0;j<nArr.length;j++)
if(nArr[j].id===t.parentId)//先比较当前节点
nArr[j].children.push(t);
return t;
if(nArr[j].children.length)//当前节点匹配不上匹配子节点
return this.compare(t,nArr[j].children);
return false;
this.makeTree();
console.log(newArr);

</script>

以上是关于把有层级的一维数组改为树形结构的主要内容,如果未能解决你的问题,请参考以下文章

js中将有层级关系的一维数据转换为父子级关系的二维数据菜单权限三级层级数据实现(树形结构数据)

JavaScript将树形结构转换一维数组

JavaScript打印JSON对象 - 树形结构输出 - 格式化JSON数组 - JS从一维数组 生成树形结构对象

JavaScript打印JSON对象 - 树形结构输出 - 格式化JSON数组 - JS从一维数组 生成树形结构对象

JavaScript打印JSON对象 - 树形结构输出 - 格式化JSON数组 - JS从一维数组 生成树形结构对象

原生JavaScript+HTML5实现树形目录结构一维数组生成多维数组detailssummary