golang生成分组树状结构

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
    }
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值