后端研发的同学对无限级分类肯定映像深刻,当初花了不少时间吧?
无限级分类树状结构的应用场景很多,例如后端研发需要把用户相关权限读取出来并生成树状结构,前端研发拿到权限树之后可以按照结构展示用户有权限访问的栏目;再例如网页上的栏目分级:
作者在初次接触树状结构生成需求的时候,也是挠头,后来找到了一个代码少且清晰易懂的生成算法:递归。
首先,确保数据库中存储的类别信息如下:
[ {"id": 1, "name": '电器', "parent": 0}, {"id": 2, "name": '水果', "parent": 0}, {"id": 3, "name": '家用电器', "parent": 1}, {"id": 4, "name": '电吹风', "parent": 3}, {"id": 5, "name": '电风扇', "parent": 3}, {"id": 6, "name": '台灯', "parent": 3}, {"id": 7, "name": '商用电器', "parent": 1}, {"id": 8, "name": '大型电热锅', "parent": 7}, ]
字段 parent 记录的是此条目的父编号,例如电吹风的父编号是 3,即电吹风属于家用电器,而家用电器的父编号是 1,即家用电器属于电器类产品。电吹风条目跟电器条目并无直接的标识进行关联,但需要用树状结构来表明 电器 <- 家用电器 <- 电吹风 的关系。
通过 parent 寻找父编号,并建立关联关系的操作实际上是循环往复的,直到找完所有的结点,这跟递归算法非常契合,很轻松便能写出对应的递归代码:
def generate_tree(source, parent): tree = [] for item in source: if item["parent"] == parent: item["child"] = generate_tree(source, item["id"]) tree.append(item) return tree
只需要将数据库中存储的信息传递给 generate_tree 函数即可。这段递归代码在往复循环的过程中通过 parent 来寻找子结点,找到子结点后将其添加到树中。完整代码如下:
import json def generate_tree(source, parent): tree = [] for item in source: if item["parent"] == parent: item["child"] = generate_tree(source, item["id"]) tree.append(item) return tree if __name__ == '__main__': permission_source = [ {"id": 1, "name": '电器', "parent": 0}, {"id": 2, "name": '水果', "parent": 0}, {"id": 3, "name": '家用电器', "parent": 1}, {"id": 4, "name": '电吹风', "parent": 2}, {"id": 5, "name": '电风扇', "parent": 3}, {"id": 6, "name": '台灯', "parent": 3}, {"id": 7, "name": '商用电器', "parent": 1}, {"id": 8, "name": '大型电热锅', "parent": 7}, ] permission_tree = generate_tree(permission_source, 0) print(json.dumps(permission_tree, ensure_ascii=False))
你试试运行一下,看看结构是否符合预期。
使用缓存优化算法
递归算法中有很多重复的计算,这些计算不仅占用额外资源,还会降低函数执行效率,因此需要对递归进行优化。这里选用缓存优化法提升函数执行效率。
基本思路是每次找到结点关系后将此条目的编号添加到一个列表中缓存起来,代表此条目已找到结点关系。当往复循环执行函数时再次遇到此条目可以跳过。代码改动很简单,增加一个缓存列表和控制流语句即可:
def generate_tree(source, parent, cache=[]): tree = [] for item in source: if item["id"] in cache: continue if item["parent"] == parent: cache.append(item["id"]) item["child"] = generate_tree(source, item["id"], cache) tree.append(item) return tree
至此,无限级分类树状结构生成算法完成。你学会了吗?
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]