JavaScript递归操作树形结构代码示例

 更新时间:2024年01月12日 10:41:15   作者:悲伤敌敌畏  
前端树形结构一般用于网页的地理位置输入框,地理位置级联选择,人员的部门选择等,这篇文章主要给大家介绍了关于JavaScript递归操作树形结构的相关资料,需要的朋友可以参考下

脚本之家 / 编程助手:解决程序员“几乎”所有问题!
脚本之家官方知识库 → 点击立即使用

树形结构转成扁平结构

数据结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let data = [
  {
    name: "1",
    children: [{
      name: "3"
    }, {
      name: "4"
    }]
  },
  {
    name: "2",
    children: [{
      name: "5"
    }, {
      name: "6",
      children: [{name: "7"}]
    }]
  }
]

转成扁平化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function dataTree(data) {
    let result = [];
    for (const item of data) {
        // result.push(item)
        result.push({ name: item.name }) // 只取当前节点的信息,不包括 children
        if (item.children === null || item.children === undefined) {
            continue;
        }
        let getChildren = dataTree(item.children)
        result = result.concat(getChildren)
    }
    return result
}
console.log("原数组结构", data);
console.log("扁平化的对象", dataTree(data));

运行结果

扁平结构转成树形结构

数据结构

1
2
3
4
5
6
7
8
9
10
let datas = [
  {id: 1, name: 1, parentId: null},
  {id: 2, name: 2, parentId: 1},
  {id: 3, name: 3, parentId: 1},
  {id: 4, name: 4, parentId: null},
  {id: 5, name: 5, parentId: 4},
  {id: 6, name: 6, parentId: 4},
  {id: 7, name: 7, parentId: 6},
  {id: 8, name: 8, parentId: 6},
]

转成树形结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function dataList(data){
  let map = {};
  for(let item of data){
    map[item.id] = item
  }
  let result = []; //存放数组
  for(let item of data){
    item.children = []; //给每个数组添加一个空children
    if(item.parentId === null){
      result.push(item)//最上级的标签
    }else{
      //相当于用这个 parentId 当做父Id去查找对比查找数据
      let parent = map[item.parentId]
      //添加到刚刚定义children数组中去
      parent.children.push(item)
    }
  }
  return result;
}
console.log("扁平化转换成树形结构:");
console.log("原数组结构",datas);
console.log("树形结构",dataList(datas));

运行结果

根据 parentId 查询对应的上级所有父节点

数据结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
const data = [
    {
        id: 1,
        parentId: undefined,
        name: 'TEST 1',
        children: [
            {
                id: 5,
                parentId:1,
                name: 'TEST 5',
                children: [
                    {
                        id: 10,
                        parentId:4,
                        name: 'TEST 10'
                    },
                    {
                        id: 11,
                        parentId:4,
                        name: 'TEST 11'
                    }
                ]
            }
        ]
    },
    {
        id: 2,
        parentId: undefined,
        name: 'TEST 2',
        children: [
            {
                id: 6,
                parentId:2,
                name: 'TEST 6'
            },
            {
                id: 7,
                parentId:2,
                name: 'TEST 7'
            }
        ]
    },
    {
        id: 3,
        parentId: undefined,
        name: 'TEST 3',
        children: [
            {
                id: 8,
                parentId:3,
                name: 'TEST 8'
            },
            {
                id: 9,
                parentId:3,
                name: 'TEST 9'
            }
        ]
    },
    {
        id: 4,
        name: 'TEST 4',
        children: [
        ]
    }
]

根据parentId查找父节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
 *
 * @param list 最外层传入的数组 也可以是 this.数组
 * @param parentId  子节点对应的上级关系parentId
 * @returns {*[]}
 */
function findP(list,parentId){
    const result = []
    /**
     * 处理逻辑
     * @param arr   要对比的数组
     * @param parentId  传递进来数据要对比父id(相当于parentId)
     */
    let forFn = function (arr,parentId){
        for (let i = 0; i < arr.length; i++) {
            let item = arr[i];
            if (item.id === parentId){
                result.push(item)
                // console.log("递归数据",item)
                // console.log("递归id",item.parentId)
                forFn(list,item.parentId)
                break
            }else {
                if (item.children){
                    forFn(item.children,parentId)
                }
            }
        }
    }
    forFn(list,parentId);
    return result;
}
console.log("数据结构==",data)
console.log("查询父类==",findP(data,11))

运行结果(会把自己及父节点保存下来)

项目中运用到的(仅供参考)

需求:根据点击子节点查询没有就一直向上查

思路:拿到树形结构数组直接递归查询

难点:

        1)获取懒加载的树形结构,(因为懒加载封装的数据结构是分开装的)

        2)拼接成树形结构在处理

下面为实现例子 只列出大概实现思路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>悲伤敌敌畏</title>
</head>
<body>
<script type="text/javascript">
/**
 分析:
 1.获取树节点的数据,
 2.因为是list结构的,先存放在map里面(递归)
 3.拼接成层级数据 返回(递归)
 4.根据parentId 查询父级(递归)
 */
const data = [
    {
        childNodes: [
            {childNodes: [{childNodes:[],data:{id: 5, name: "测试5", parentId: 3}}], data: {id: 3, name: "测试3", parentId: 1}},
            {childNodes: [], data: {id: 4, name: "测试4", parentId: 1}}
        ],
        data: {id: 1, name: "测试1", parentId: null}
    },
    {
        childNodes: [],
        data: {id: 2, name: "测试2", parentId: null}
    },
];
console.info("要处理的数据结构 >>>",data)
 
    //使用函数
    forChildren(data)
 
    function forChildren(list){
        //TODO 转成map结构,用于比较
        let map = {};
        let forMap = function (arr){
            for (const item of arr) {
                map[item.data.id] = item.data
                if (item.childNodes.length > 0){
                    forMap(item.childNodes)
                }
            }
        }
        forMap(list)
        console.log("封装的map >>>",map)
 
 
        //TODO 拼接成层级数据:
        let result = [];
        let forList =function(arr){
            for (const item of arr) {
                item.data.children = [] //为每个data添加一个数组
                if (item.data.parentId === null){ //判断是否为最外层(最外层一般都是空或者-1)
                    result.push(item.data)
                }
                if (item.childNodes.length > 0){
                    for (const children of item.childNodes) {
                        let paren = map[children.data.parentId]
                        paren.children.push(children.data)
                        forList(item.childNodes)
                    }
                }
            }
        }
        forList(list)
        console.log("拼接好的树形结构",result)
 
 
        //TODO 根据子节点查找上面的每个父节点
        let parents = []
        let forParent = function (arr,parentId){
            for (const item of arr) {
                if (item.id === parentId){
                    parents.push(item)
                    forParent(result,item.parentId)
                    break
                }else {
                    if (item.children){
                        forParent(item.children,parentId)
                    }
                }
            }
        }
        forParent(result,5)
        console.log("父级以及自己的数据",parents)
         
    }
</script>
</body>
</html>

总结 

到此这篇关于JavaScript递归操作树形结构的文章就介绍到这了,更多相关js递归操作树形结构内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

蓄力AI

微信公众号搜索 “ 脚本之家 ” ,选择关注

程序猿的那些事、送书等活动等着你

原文链接:https://blog.csdn.net/weixin_53990507/article/details/128296917

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!

相关文章

最新评论