`
leeqq
  • 浏览: 141201 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

将有层级标志的数组转为树状结构

    博客分类:
  • web
 
阅读更多

最近项目中遇到了将数组形式的菜单转化为树状结构的菜单

例如,原始数据是

 

[
    {id: 1,  parentId: 0, name: '第一级菜单A' },
    {id: 2,  parentId: 0, name: '第一级菜单B' },
    {id: 3,  parentId: 1, name: '第二级菜单A' },
    {id: 4,  parentId: 1, name: '第二级菜单B' },
    {id: 5,  parentId: 3, name: '第三级菜单A' },
    {id: 6,  parentId: 3, name: '第三级菜单B' },
    {id: 7,  parentId: 4, name: '第三级菜单C' },
    {id: 8,  parentId: 4, name: '第三级菜单D' },
    {id: 9,  parentId: 2, name: '第二级菜单C' },
    {id: 10, parentId: 2, name: '第二级菜单D' }
]

 转化为

 

  

 

 

需求已经明确,现在就看是怎么实现的

 

两次对数组两次循环

第一次循环

    找到所有第一级菜单放入数组A,其余的放入另一个数组B,并将所有菜单以id作为key放入一个对象C中,

第二次循环

    对数组B循环,通过parentId到对象C中找到父级,并push到父级的children数组中。

通过这两次循环,已经转化完成,代码如下

 

function array2tree (arr) {
    var top = [], sub = [], arrObj = {};

    arr.forEach(function (item) {
        if (item.parentId === 0) {
            top.push(item);
        } else {
            sub.push(item);
        }
        item.children = [];
        arrObj[item.id] = item;
    });

    sub.forEach(function (item) {
        var parent = arrObj[item.parentId] || {'children': []};
        parent.children.push(item);
    });

    return top;
}

 

 

那么问题来了,能否通过一次循环就解决问题,答案是可以的

在循环过过程中将第一级菜单放入数组A,将所有菜单以id作为key放入对象B中,同时以parentId作为key在对象B中找到其父级,并将其push到父级的children中,在这一步需要注意的是,如果子级先出现,那么就有可能在对象B中找不到父级。所以这里要作点处理,具体如下

如果子级先出现,在对象B中找不到父级,这是要在对象B中创建一个对象作为临时的父级,并将子级push到这个临时的父级children中。当然这个子菜单也要放入对象B中

这是又会出现另外一个问题,当真正的父级出现时,对象B中已经存在一个临时的父级时,这时要作的处理是将临时的父级的属性扩展到真正的父级中,并用真正的父级替换对象B中的临时父级。

 

哈哈,真绕,看代码

function array2tree (arr) {
    var top = [], arrObj = {};

    arr.forEach(function (item) {
        var id = item.id, parentId = item.parentId, parent, own;
        if (parentId === 0) {
            top.push(item);
        }

        item.children = [];
        own = arrObj[id];
        if (own) {
            Object.keys(own).forEach(function (key) {
                item[key] = own[key];
            });
        }
        arrObj[id] = item;

        parent = arrObj[parentId];
        if (!parent) {
            parent = {'id': parentId, 'children': []};
            arrObj[parentId] = parent;
        }
        parent.children.push(item);

    });
    return top;
}

 

  • 大小: 4.1 KB
  • 大小: 30.3 KB
分享到:
评论

相关推荐

    java将list转为树形结构的方法(后台和前台)

    标题中的“java将list转为树形结构的方法(后台和前台)”指的是在Java编程语言中,如何将一个列表(List)数据结构转换为树形结构。这种转换通常用于处理层级关系的数据,如目录结构、组织架构等。转换分为前端...

    js代码-数组根据pid转为树形结构的数组

    本案例中的"js代码-数组根据pid转为树形结构的数组"涉及到的就是将一个基于父级ID(PID)的扁平化数组转换为树形结构的数组。这种转换在构建组织结构、文件系统或者菜单导航等场景中非常常见。 首先,我们来理解...

    把扁平化的数据转换成树形结构的JSON

    而树形结构则是一种分层的数据结构,每个节点(数据元素)可以有零个或多个子节点,形成了一个层级分明的结构。 在JavaScript中,我们可以用对象来表示树的节点,每个对象包含自身的数据以及指向其子节点的引用。...

    js 实现 list转换成tree的方法示例(数组到树)

    在JavaScript中,将一个列表(list)转换为树形结构(tree)是常见的需求,特别是在处理具有层级关系的数据时,例如组织结构、菜单系统等。本文将详细介绍如何使用JavaScript实现这个转换过程,以一个简单的例子作为...

    javascript将扁平的数据转为树形结构的高效率算法

    在JavaScript编程中,将扁平的数据结构转换为树形结构是一项常见的任务,特别是在处理层级关系的数据时,如组织结构、菜单导航或文件系统等。在本文中,我们将深入探讨一种高效的算法,该算法可以将一维数组转换为...

    用javascript实现的TreeTable, 可以当做树(Tree)用

    JavaScript中的TreeTable是一种将数据以树状结构展示的表格,常用于组织层次分明的数据,例如部门结构、文件系统等。这种数据结构允许用户通过展开和折叠节点来查看和操作数据的层级关系。在这个场景中,`TreeTable....

    js代码-树形结构转换

    在处理这种数据时,我们经常需要将树形结构进行转换,比如从数组形式转为对象形式,或者反之。本篇将重点讲解如何在JavaScript中进行树形结构的转换。 **1. 数组到树形结构的转换** 数组通常用来存储扁平化的树...

    mind-maps-to-json:思维导图到 JSON 数据对象

    思维导图通常以中心主题为核心,向外辐射出多个分支,每个分支又可以衍生出子分支,以此类推,形成层次分明的树状结构。在编程中,这种结构可以用树形数据结构来表示,包括节点(node)、父节点(parent node)、子...

Global site tag (gtag.js) - Google Analytics