资讯专栏INFORMATION COLUMN

列表转树的实现思路与代码

starsfun / 3119人阅读

摘要:执行步骤遍历每一个列表项,对比该项与列表内所有项的,根据对比结果做后续处理如果该项与列表中某项相等,那么把作为的孩子。这里应该还有可优化的地方,欢迎大家提供更多更好的思路,恳请在补充新的方案时,先把思路说清楚,切勿直接扔代码上来。

背景

在前端开发中,有一种组件是每个前端都绕不过去的,树组件。在业务中像目录结构、组织架构、行政区域划分这些都是典型的树组件使用场景。一般来说,前端也就是拿来一个封装好的控件,然后传入符合要求的数据结构就完事了。但是,有的时候我们拿到的东西可能并不完美,比如服务端给我们返回了一个列表,列表中每一项之间的父子关系通过id与parentId来确定,那么问题来了,我们如何在前端把这样的列表数据转换成树结构的数据呢?想过么?做过么?做得出来么?
我搜索了一大圈,发现绝大部分都是把代码一贴就完事,根本不讲思路是什么,为了能一劳永逸的解决这个问题,我觉得先把思路理清是最重要的,至于怎么实现,就是coding的问题了,coding就看每个人心情了,每个人都有自己喜欢的方式,个人不建议把coding写死,僵化。

思路分析

需求是什么?

大概是这个样子,应该一目了然了。

先说一下整体思路,根据parentId和id把数组中的每一项的父节点找到,并将自己作为父节点的children中的一项,所有的数据项都处理完毕后,其实就差不多了,最后我们把根节点找到并返回,转换完成。

执行步骤

遍历每一个列表项,对比该项(currentItem)parentId与列表内所有项的id,根据对比结果做后续处理

如果该项parentId与列表中某项(parentItem)id相等,那么把currentItem作为parentItem的孩子。也就是把currentItem作为parentItem的children中的一项。

执行完上述过程后,列表中对应的父子关系就已经处理完毕了,此时我们需要找出根节点就可以了,判断根节点的方法很简单,就是parentId为null的项。

代码
const List = [
    {id: 1, name: "child1", parentId: 0},
    {id: 2, name: "child2", parentId: 0},
    {id: 6, name: "child2_1", parentId: 2},
    {id: 0, name: "root", parentId: null},
    {id: 5, name: "child1_2", parentId: 1},
    {id: 4, name: "child1_1", parentId: 1},
    {id: 3, name: "child3", parentId: 0},
    {id: 7, name: "child3_1", parentId: 3}
]

function ListToTree (list) {
    const copyList = list.slice(0)
    const tree = []
    for (let i = 0;i < copyList.length;i++) {
        // 找出每一项的父节点,并将其作为父节点的children
        for (let j = 0;j < copyList.length;j++) {
            if (copyList[i].parentId === copyList[j].id) {
                if (copyList[j].children === undefined) {
                    copyList[j].children = []
                }
                copyList[j].children.push(copyList[i])
            }
        }
        // 把根节点提取出来,parentId为null的就是根节点
        if (copyList[i].parentId === null) {
            tree.push(copyList[i])
        }
    }
    return tree
}

const tree = ListToTree(List)
console.log(JSON.stringify(tree))

上面代码直接扔到浏览器中即可运行,可自行看看结果。这里先把结果放在下面,供参考。
[{"id":0,"name":"root","parentId":null,"children":[{"id":1,"name":"child1","parentId":0,"children":[{"id":5,"name":"child1_2","parentId":1},{"id":4,"name":"child1_1","parentId":1}]},{"id":2,"name":"child2","parentId":0,"children":[{"id":6,"name":"child2_1","parentId":2}]},{"id":3,"name":"child3","parentId":0,"children":[{"id":7,"name":"child3_1","parentId":3}]}]}]
以上结果放到https://www.bejson.com/jsoned...中查看,效果更佳。

总结

列表转树的过程,我这里用了两层循环,然后利用了js的对象引用机制,将列表转成了树,其实这个过程中已经改变了原有的列表数据结构(循环结束后打印copyList即可看到结果),所以在第一步的时候才先复制了一个列表进来。这里应该还有可优化的地方,欢迎大家提供更多更好的思路,恳请在补充新的方案时,先把思路说清楚,切勿直接扔代码上来。交流、沟通、理解效果才好。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95383.html

相关文章

  • 树转列表实现思路代码

    摘要:背景之前写了一篇列表转树的文章,有列表转树的需求自然就会有树转列表的需求,这里我把树转列表的思路与代码再整理一下。总结树转列表过程中,我这里的深度优先采用了递归方式,可能会对内存占用较多,使用时请自行权衡。 背景 之前写了一篇列表转树的文章,有列表转树的需求自然就会有树转列表的需求,这里我把树转列表的思路与代码再整理一下。 思路分析 需求是什么?老规矩,上图showImg(https:...

    denson 评论0 收藏0
  • js “指针”:数组转树

    摘要:当变量指向一个对象的时候,实际指向的是存储地址测试结果数组转树的方式节点节点节点节点节点节点节点节点将作为键值方便二次遍历做索引为的是根节点这样只要遍历俩次第一次遍历将数组转节点对象,存储到新的对象里,为键值方便索引第二次遍历根据索引插入子 当变量指向一个对象的时候,实际指向的是存储地址测试: a = {val: 123} b = a b.val = 321 ...

    mikyou 评论0 收藏0
  • 轻松实现可扩展的树形表格

    摘要:由于目前还未开发树形表格组件,也参阅了网络上部分基于表格封装的开源树形组件,都没有找的太理想可进行二次开发的开源项目,所以就萌生了自行开发树形表格。 由于ElementUI目前还未开发树形表格组件,也参阅了网络上部分基于ElementUI表格封装的开源树形组件,都没有找的太理想可进行二次开发的开源项目,所以就萌生了自行开发树形表格。 本示例提供开发思路,移除了多余的样式,比较适合新手入...

    harryhappy 评论0 收藏0
  • js 中二叉树的深度遍历广度遍历(递归实现非递归实现)

    摘要:树中结点的最大层次称为树的深度或高度。二叉树有深度遍历和广度遍历,深度遍历有前序中序和后序三种遍历方法。二叉树的前序遍历可以用来显示目录结构等中序遍历可以实现表达式树,在编译器底层很有用后序遍历可以用来实现计算目录内的文件及其信息等。 树的简介 栈、队列、链表等数据结构,都是顺序数据结构。而树是非顺序数据结构。树型结构是一类非常重要的非线性结构。直观地,树型结构是以分支关系定义的层次结...

    Yuanf 评论0 收藏0
  • Python数据结构——树的实现

    摘要:列表的第二个元素的本身是一个表示左子树的列表。子树具有根节点和两个表示叶节点的空列表。重要的是要记住这种表示的是左右子树引用的是其他二叉树的实例。为了完成一个简单的二叉树数据结构的定义,我们写出访问参见左右子节点和根值的方法。 嵌套列表表示树 在用嵌套列表表示树时,我们使用 Python 的列表来编写这些函数。虽然把界面写成列表的一系列方法与我们已实现其他的抽象数据类型有些不同,但这样...

    tain335 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<