WordPress适合做多大级别的网站,自助建站哪个网站好,个人做企业网站制作要多少钱,爱站工具包的模块背景
相信大家都遇到过树形结构#xff0c;像是文件列表、多级菜单、评论区的设计等等#xff0c;我们都发现它有很多层级#xff0c;第一级可以有多个#xff0c;下边的每一个层级也可以有多个#xff1b;有的可以设计成无限层级的#xff0c;有的只能设计成两级。那么…背景
相信大家都遇到过树形结构像是文件列表、多级菜单、评论区的设计等等我们都发现它有很多层级第一级可以有多个下边的每一个层级也可以有多个有的可以设计成无限层级的有的只能设计成两级。那么作为程序员我觉得应该具备这种思维程序的拓展性。就像shigen接手需求一样上次接到了评论回复的需求产品觉得两级回复和多级回复可以分成两期做细心的我就发现这完全可以整成一个需求做呢。于是我一次性把之后的都做了。
我们先分析一下具体的场景
我们常常会遇到多级文件类似我们电脑的文件管理系统。我们可以把每个文件夹和文件抽象一下在linux系统中文件就包括文本文件和文件夹。OK万物皆文件shigen就在这里狂一下。那它们要根据什么关联起来呢数据库怎么存储呢 分析
目前我们主要的解决方案是这样的。 item_list [Item(111, one, None, None),Item(111-1, one, None, None),Item(222, two, 111, None),Item(333, three, 111, None),Item(444, four, 333, None),Item(444-1, four, 333, None),Item(444-2, four, 444-1, None),]我们只需要存储单条数据就可以那它们的关联就需要构造函数的第三个参数pid保存自己上一个节点的id如果上一个节点的idpid是空的OK那它就是第一级别的。注意第一级别的可能有多个。Item的构造方法是这样的
class Item():def __init__(self, id: int, name: str, pid: Optional[int], children: Optional[List]):self.id idself.name nameself.pid pidself.__children children那么分析起来发现就是几句话代码怎么实现呢shigen在这里列举了两种语言的实现方式java和python。来一起看看吧
代码实现
Java
在来到Java这一步我不会使用传统的递归的方式我使用的是java8所以我更喜欢用streamlambda表达式写起来异常的简洁别人不夸优雅都不行
Item类的定义和python代码案例的是一样的java的定义是这样的 DataAllArgsConstructorstatic class Item {private Integer id;private String name;private Integer pid;private ListItem children;}那怎么实现这个tree结构呢shigen用的一个函数仅仅三行代码是三行 private static ListItem getTree(ArrayListItem items) {// 获得非顶级节点的数据并按照pid分组MapInteger, ListItem nodeMap items.stream().filter(item - item.getPid() ! null).collect(Collectors.groupingBy(Item::getPid));// 循环设置子节点items.forEach(item - item.setChildren(nodeMap.get(item.id)));// 获得根节点的数据ListItem treeNode items.stream().filter(node - node.getPid() null).collect(Collectors.toList());return treeNode;}这是一个通用的方法我把我的代码截图也贴上来。 这边shigen也在思考把这个方法做成通用的这样就可以作为一个工具类使用了。也欢迎伙伴们来交流一下。
python
shigen对这个案例提供了双语言的支持。但是不得不说在和java的stream对比之下python的代码还是显得比较繁琐了。但是也是一种解决思路和参考。
def build_tree_structure(items:List[Item]) - List[Item]:# 获得顶级节点treeNode list(filter(lambda item: item.pid is None, items))for node in treeNode:node.children get_children(node, items)return treeNodedef get_children(root:Item, items:List[Item]) - Item:children []for item in items:if item.pid root.id:item.children get_children(item, items)children.append(item)return children其实这里用到了递归的方式先获得所有的第一级节点然后根据第一层节点的id去匹配子级的id。这样重复的步骤就可以使用递归来实现了递归的终止条件就是item.pid ! root.id。这个代码shigen目前已经写到最简洁了还有其它的优化思路的也欢迎评论区交流一下。
最后贴上我的python代码实现截图 好了以上就是shigen和大家分享的树形结构的快速生成的全部内容了。
与shigen一起每天不一样