1.需求: 获取分组导航树
2.实现
package main
import (
"encoding/json"
"fmt"
"strings"
)
type Group struct {
Id int `json:"id"`
Alias string `json:"alias"`
FullAlias string `json:"fullAlias"`
ParentId int `json:"parentId"`
ParentAlias string `json:"parentAlias"`
ParentFullAlias string `json:"parentFullAlias"`
Children []*Group `json:"children"`
}
func getTreeRecursive(list []*Group, parentId int, parentAlias string) []*Group {
res := make([]*Group, 0)
for _, v := range list {
if v.ParentId == parentId {
if parentAlias != "" {
v.FullAlias = parentAlias + "/" + v.Alias
} else {
v.FullAlias = v.Alias
}
v.ParentFullAlias = parentAlias
fullList := strings.Split(v.FullAlias, "/")
if len(fullList) >= 2 {
v.ParentAlias = fullList[len(fullList)-2]
} else {
v.ParentAlias = parentAlias
}
v.Children = getTreeRecursive(list, v.Id, v.FullAlias)
// 用 alias 排序,alias相等的元素保持原始顺序
sort.SliceStable(v.Children, func(i, j int) bool {
return v.Children[i].Alias < v.Children[j].Alias
})
res = append(res, v)
}
}
// 用 alias 排序,alias相等的元素保持原始顺序
sort.SliceStable(res, func(i, j int) bool {
return res[i].Alias < res[j].Alias
})
return res
}
func main() {
list := []*Group{
{
1, "FPF引擎", "", 0, "", "", []*Group{
}},
{
2, "IDP引擎", "", 0, "", "", []*Group{
}},
{
3, "桂妃山", "", 1, "", "", []*Group{
}},
{
4, "南沙", "", 1, "", "", []*Group{
}},
{
5, "大边", "", 1, "", "", []*Group{
}},
{
6, "一场", "", 3, "", "", []*Group{
}},
{
9, "一线", "", 6, "", "", []*Group{
}},
{
7, "二场", "", 3, "", "", []*Group{
}},
{
10, "一线", "", 7, "", "", []*Group{
}},
{
8, "洗消中心", "", 5, "", "", []*Group{
}},
}
res := getTreeRecursive(list, 0, "")
bytes, _ := json.MarshalIndent(res, "", " ")
fmt.Printf("%s\n", bytes)
}
结果示例:
[
{
"id": 1,
"alias": "FPF引擎",
"fullAlias": "FPF引擎",
"parentId": 0,
"parentAlias": "",
"parentFullAlias": "",
"children": [
{
"id": 3,
"alias": "桂妃山",
"fullAlias": "FPF引擎/桂妃山",
"parentId": 1,
"parentAlias": "FPF引擎",
"parentFullAlias": "FPF引擎",
"children": [
{
"id": 6,
"alias": "一场",
"fullAlias": "FPF引擎/桂妃山/一场",
"parentId": 3,
"parentAlias": "桂妃山",
"parentFullAlias": "FPF引擎/桂妃山",
"children": [
{
"id": 9,
"alias": "一线",
"fullAlias": "FPF引擎/桂妃山/一场/一线",
"parentId": 6,
"parentAlias": "一场",
"parentFullAlias": "FPF引擎/桂妃山/一场",
"children": []
}
]
},
{
"id": 7,
"alias": "二场",
"fullAlias": "FPF引擎/桂妃山/二场",
"parentId": 3,
"parentAlias": "桂妃山",
"parentFullAlias": "FPF引擎/桂妃山",
"children": [
{
"id": 10,
"alias": "一线",
"fullAlias": "FPF引擎/桂妃山/二场/一线",
"parentId": 7,
"parentAlias": "二场",
"parentFullAlias": "FPF引擎/桂妃山/二场",
"children": []
}
]
}
]
},
{
"id": 4,
"alias": "南沙",
"fullAlias": "FPF引擎/南沙",
"parentId": 1,
"parentAlias": "FPF引擎",
"parentFullAlias": "FPF引擎",
"children": []
},
{
"id": 5,
"alias": "大边",
"fullAlias": "FPF引擎/大边",
"parentId": 1,
"parentAlias": "FPF引擎",
"parentFullAlias": "FPF引擎",
"children": [
{
"id": 8,
"alias": "洗消中心",
"fullAlias": "FPF引擎/大边/洗消中心",
"parentId": 5,
"parentAlias": "大边",
"parentFullAlias": "FPF引擎/大边",
"children": []
}
]
}
]
},
{
"id": 2,
"alias": "IDP引擎",
"fullAlias": "IDP引擎",
"parentId": 0,
"parentAlias": "",
"parentFullAlias": "",
"children": []
}
]
3. 额外获取每个分组对应的父分组信息及分组的层级名称全称
package main
import (
"encoding/json"
"fmt"
"strings"
)
type Group struct {
Id int `json:"id"`
Alias string `json:"alias"`
FullAlias string `json:"fullAlias"`
ParentId int `json:"parentId"`
ParentAlias string `json:"parentAlias"`
ParentFullAlias string `json:"parentFullAlias"`
Children []*Group `json:"children"`
}
func getTreeRecursive(list []*Group, parentId int, parentAlias string) []*Group {
res := make([]*Group, 0)
for _, v := range list {
if v.ParentId == parentId {
if parentAlias != "" {
v.FullAlias = parentAlias + "/" + v.Alias
} else {
v.FullAlias = v.Alias
}
v.ParentFullAlias = parentAlias
fullList := strings.Split(v.FullAlias, "/")
if len(fullList) >= 2 {
v.ParentAlias = fullList[len(fullList)-2]
} else {
v.ParentAlias = parentAlias
}
v.Children = getTreeRecursive(list, v.Id, v.FullAlias)
// 用 alias 排序,alias相等的元素保持原始顺序
sort.SliceStable(v.Children, func(i, j int) bool {
return v.Children[i].Alias < v.Children[j].Alias
})
res = append(res, v)
}
}
// 用 alias 排序,alias相等的元素保持原始顺序
sort.SliceStable(res, func(i, j int) bool {
return res[i].Alias < res[j].Alias
})
return res
}
func getGroupMapper(group []*Group, re map[int]map[string]interface{
}) map[int]map[string]interface{
} {
for _, v := range group {
temp := map[string]interface{
}{
"alias": v.Alias,
"fullAlias": v.FullAlias,
"parentFullAlias": v.ParentFullAlias,
"parentId": v.ParentId,
"parentAlias": v.ParentAlias,
}
re[v.Id] = temp
if len(v.Children) > 0 {
getGroupMapper(v.Children, re)
}
}
return re
}
// 检查指定父分组下是否有重名的子分组名称
func findChildAlias(alias string, parentId int, tree []*Group) bool {
var res bool
for _, v := range tree {
if v.ParentId == parentId {
if v.Alias == alias {
res = true
break
} else {
continue
}
}else{
res = findChildAlias(alias, parentId, v.Children)
}
}
return res
}
func main() {
list := []*Group{
{
1, "FPF引擎", "", 0, "", "", []*Group{
}},
{
2, "IDP引擎", "", 0, "", "", []*Group{
}},
{
3, "桂妃山", "", 1, "", "", []*Group{
}},
{
4, "南沙", "", 1, "", "", []*Group{
}},
{
5, "大边", "", 1, "", "", []*Group{
}},
{
6, "一场", "", 3, "", "", []*Group{
}},
{
9, "一线", "", 6, "", "", []*Group{
}},
{
7, "二场", "", 3, "", "", []*Group{
}},
{
10, "一线", "", 7, "", "", []*Group{
}},
{
8, "洗消中心", "", 5, "", "", []*Group{
}},
}
res := getTreeRecursive(list, 0, "")
bytes, _ := json.MarshalIndent(res, "", " ")
fmt.Printf("%s\n", bytes)
cacheMap := getGroupMapper(res, map[int]map[string]interface{
}{
})
bytes2, _ := json.MarshalIndent(cacheMap, "", " ")
fmt.Printf("%s\n", bytes2)
}
fmt.Println(findChildAlias("FPF引擎",0, tree)) // true
fmt.Println(findChildAlias("桂妃山",1, tree)) // true
fmt.Println(findChildAlias("桂妃山1",1, tree)) // false
fmt.Println(findChildAlias("一场",3, tree)) // true
fmt.Println(findChildAlias("一场1",3, tree)) // false
fmt.Println(findChildAlias("一线",6, tree)) // true
fmt.Println(findChildAlias("一线1",6, tree)) // false
结果示例:
{
"1": {
"alias": "FPF引擎",
"fullAlias": "FPF引擎",
"parentAlias": "",
"parentFullAlias": "",
"parentId": 0
},
"10": {
"alias": "一线",
"fullAlias": "FPF引擎/桂妃山/二场/一线",
"parentAlias": "二场",
"parentFullAlias": "FPF引擎/桂妃山/二场",
"parentId": 7
},
"2": {
"alias": "IDP引擎",
"fullAlias": "IDP引擎",
"parentAlias": "",
"parentFullAlias": "",
"parentId": 0
},
"3": {
"alias": "桂妃山",
"fullAlias": "FPF引擎/桂妃山",
"parentAlias": "FPF引擎",
"parentFullAlias": "FPF引擎",
"parentId": 1
},
"4": {
"alias": "南沙",
"fullAlias": "FPF引擎/南沙",
"parentAlias": "FPF引擎",
"parentFullAlias": "FPF引擎",
"parentId": 1
},
"5": {
"alias": "大边",
"fullAlias": "FPF引擎/大边",
"parentAlias": "FPF引擎",
"parentFullAlias": "FPF引擎",
"parentId": 1
},
"6": {
"alias": "一场",
"fullAlias": "FPF引擎/桂妃山/一场",
"parentAlias": "桂妃山",
"parentFullAlias": "FPF引擎/桂妃山",
"parentId": 3
},
"7": {
"alias": "二场",
"fullAlias": "FPF引擎/桂妃山/二场",
"parentAlias": "桂妃山",
"parentFullAlias": "FPF引擎/桂妃山",
"parentId": 3
},
"8": {
"alias": "洗消中心",
"fullAlias": "FPF引擎/大边/洗消中心",
"parentAlias": "大边",
"parentFullAlias": "FPF引擎/大边",
"parentId": 5
},
"9": {
"alias": "一线",
"fullAlias": "FPF引擎/桂妃山/一场/一线",
"parentAlias": "一场",
"parentFullAlias": "FPF引擎/桂妃山/一场",
"parentId": 6
}
}