将扁平的数据转为树形结构 层级部门人数统计 递归
def get_tree_ids(tree: dict, keyword='id', child_name="children") -> list:
'''
求树的全部节点的id
方法:1、递归;2、数据库遍历parent_id查询
'''
ids = [tree[keyword]]
children = tree.get(child_name)
if children:
for child in children:
ids += get_tree_ids(child)
return ids
def find_sub_tree(tree: dict, keyword_val, keyword='id', child_name="children") -> dict | None:
'''
求子树
'''
if tree[keyword] == keyword_val:
return tree
children = tree.get(child_name)
ret = None
if children:
for child in children:
ret = find_sub_tree(child, keyword_val)
if ret:
break
return ret
case = {'id': 75, 'name': '测试用例', 'parent_id': None,
'person_num': 22, 'children': [
{'id': 76, 'name': '广告发行中心', 'parent_id': 75,
'person_num': 14, 'children': [
{'id': 77, 'name': '广告商务组', 'parent_id': 76, 'person_num': 0},
{'id': 78, 'name': '广告投放组', 'parent_id': 76, 'person_num': 5},
{'id': 79, 'name': '广告设计组', 'parent_id': 76, 'person_num': 7},
{'id': 80, 'name': '发行运营组', 'parent_id': 76,
'person_num': 1}]},
{'id': 81, 'name': '技术部', 'parent_id': 75, 'person_num': 6},
{'id': 82, 'name': '创意设计部', 'parent_id': 75, 'person_num': 0}]}
case1 = {'id': 13, 'name': 'A团队', 'parent_id': None, 'person_num': 12,
'children': [{'id': 61, 'name': '项目二', 'parent_id': 13, 'person_num': 4,
'children': [{'id': 111, 'name': '测试部门', 'parent_id': 61,
'person_num': 3, 'children': [
{'id': 10197, 'name': 'testDep0', 'parent_id': 111,
'person_num': 0, 'children': [
{'id': 10199, 'name': 'testDep0-0',
'parent_id': 10197, 'person_num': 0}]},
{'id': 10198, 'name': 'testDep1', 'parent_id': 111,
'person_num': 3, 'children': [
{'id': 10200, 'name': 'testDep1-0',
'parent_id': 10198, 'person_num': 3}]}]}]},
{'id': 62, 'name': '项目三', 'parent_id': 13, 'person_num': 4,
'children': [{'id': 64, 'name': '子项目一', 'parent_id': 62,
'person_num': 4}]}]}
小结:
1、借助指针,2个循环搞定;
2、支持无限层级的树状结构。
type T struct {
domain.VOGoodsCat
Children []*T
}
flat := func() []domain.VOGoodsCat {
flat := []domain.VOGoodsCat{}
for _, v := range out.List {
u := domain.VOGoodsCat{}
u.ParentId = v.ParentId
u.CategoryId = v.CategoryId
u.ParentId = v.ParentId
u.Name = v.Name
flat = append(flat, u)
}
return flat
}()
treeList := func() []T {
// TODO 族谱树 多叉树
treeList := []T{}
flatPtr := []T{}
for _, i := range flat {
t := T{}
t.CategoryId = i.CategoryId
t.ParentId = i.ParentId
t.Name = i.Name
t.Children = []*T{}
flatPtr = append(flatPtr, t)
}
for m := range flatPtr {
for n := range flatPtr {
if flatPtr[m].CategoryId == flatPtr[n].ParentId {
flatPtr[m].Children = append(flatPtr[m].Children, &flatPtr[n])
}
}
}
for _, j := range flatPtr {
if j.ParentId == -1 {
treeList = append(treeList, j)
}
}
return treeList
}()
如果Children无数据,从返回空数组调整为null
[]*T -->> *[]*T nil
type T struct {
domain.VOGoodsCat
Children *[]*T
}
flat := func() []domain.VOGoodsCat {
flat := []domain.VOGoodsCat{}
for _, v := range out {
u := domain.VOGoodsCat{}
u.ParentId = v.ParentId
u.CategoryId = v.CategoryId
u.ParentId = v.ParentId
u.Name = v.Name
flat = append(flat, u)
}
return flat
}()
treeList := func() []T {
// TODO 族谱树 多叉树
treeList := []T{}
flatPtr := []T{}
for _, i := range flat {
t := T{}
t.CategoryId = i.CategoryId
t.ParentId = i.ParentId
t.Name = i.Name
t.Children = nil
flatPtr = append(flatPtr, t)
}
for m := range flatPtr {
for n := range flatPtr {
if flatPtr[m].CategoryId == flatPtr[n].ParentId {
if flatPtr[m].Children == nil {
flatPtr[m].Children = &[]*T{}
}
*(flatPtr[m].Children) = append(*(flatPtr[m].Children), &flatPtr[n])
}
}
}
for _, j := range flatPtr {
if j.ParentId == -1 {
treeList = append(treeList, j)
}
}
return treeList
}()
def list_to_tree(lst: list, parent_id, keyword='id', parent_name="parent_id", child_name="children") -> list:
hashmap = {}
tree = []
for data in lst:
if data[parent_name] == parent_id:
tree.append(data)
hashmap[data[keyword]] = data
for data in lst:
parent = hashmap.get(data[parent_name])
if parent is None:
continue
if parent.get(child_name) is None:
parent[child_name] = []
parent[child_name].append(data)
return tree
def list_to_tree_with_count(lst: list, parent_id, keyword='id', parent_name="parent_id", child_name="children",
num_name="person_num") -> list:
tree_list = list_to_tree(lst, parent_id, keyword=keyword, parent_name=parent_name, child_name=child_name)
'''
测试sql
SELECT u.`name`,u.create_time,c.id,c.parent_id ,c.`name`
FROM account_user u right JOIN center_company_department c ON u.dept_id=c.id WHERE
c.id IN (70200,70198,70199,70197,61,111,13,62,64,10169) ORDER BY c.id DESC,c.parent_id DESC;
'''
def sum_tree(node):
'''
求树节点的和
'''
total = 0
if num_name in node:
total = node[num_name]
if child_name in node:
for i in node[child_name]:
total += sum_tree(i)
return total
def r(node) -> None:
'''
递归
求出各个节点的后代的和
'''
node[num_name] = sum_tree(node)
if child_name in node:
for i in node[child_name]:
r(i)
return
for i in tree_list:
r(i)
return tree_list
应用场景:
层级部门人数统计
翻译
搜索
复制

浙公网安备 33010602011771号