下面是详细讲解 golang 通过递归遍历生成树状结构的操作的完整攻略。
操作步骤
- 定义节点结构体
首先需要定义节点结构体,表示每一个节点的信息。
type Node struct {
ID int // 节点 ID
Name string // 节点名称
ParentID int // 父节点 ID
Children []*Node // 子节点
}
- 创建节点数组
创建一个节点数组,用于存储所有节点信息。
var treeData = []*Node{
{ID: 1, Name: "节点 1", ParentID: 0},
{ID: 2, Name: "节点 2", ParentID: 1},
{ID: 3, Name: "节点 3", ParentID: 2},
{ID: 4, Name: "节点 4", ParentID: 1},
{ID: 5, Name: "节点 5", ParentID: 0},
{ID: 6, Name: "节点 6", ParentID: 5},
{ID: 7, Name: "节点 7", ParentID: 6},
}
- 定义递归函数
定义一个递归函数 buildTree
,用于递归生成树状结构。
func buildTree(parentID int, data []*Node) []*Node {
var tree []*Node
for _, v := range data {
if v.ParentID == parentID {
children := buildTree(v.ID, data)
v.Children = children
tree = append(tree, v)
}
}
return tree
}
该递归函数接受两个参数,分别是父节点 ID 和节点数组,返回生成的树状结构。
递归函数的核心就是在循环节点数组时,判断当前节点的父节点 ID 是否等于传入的父节点 ID。如果等于,表示当前节点为传入节点的子节点,需要继续往下递归。
- 生成树状结构
调用 buildTree
函数,传入根节点的父节点 ID 和包含所有节点信息的数组 treeData
,即可生成树状结构。
tree := buildTree(0, treeData)
- 输出结果
最后,使用 json.Marshal
将生成的树状结构转换为 JSON 格式并输出。
treeJSON, err := json.Marshal(tree)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(treeJSON))
示例说明
- 根据节点数组生成树状结构
假设有以下节点数组:
var treeData = []*Node{
{ID: 1, Name: "节点 1", ParentID: 0},
{ID: 2, Name: "节点 2", ParentID: 1},
{ID: 3, Name: "节点 3", ParentID: 2},
{ID: 4, Name: "节点 4", ParentID: 1},
{ID: 5, Name: "节点 5", ParentID: 0},
{ID: 6, Name: "节点 6", ParentID: 5},
{ID: 7, Name: "节点 7", ParentID: 6},
}
调用 buildTree
函数,传入根节点的父节点 ID 和节点数组,即可生成树状结构。最后将结果转换为 JSON 格式并输出。
tree := buildTree(0, treeData)
treeJSON, err := json.Marshal(tree)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(treeJSON))
输出结果为:
[
{
"ID": 1,
"Name": "节点 1",
"ParentID": 0,
"Children": [
{
"ID": 2,
"Name": "节点 2",
"ParentID": 1,
"Children": [
{
"ID": 3,
"Name": "节点 3",
"ParentID": 2,
"Children": null
}
]
},
{
"ID": 4,
"Name": "节点 4",
"ParentID": 1,
"Children": null
}
]
},
{
"ID": 5,
"Name": "节点 5",
"ParentID": 0,
"Children": [
{
"ID": 6,
"Name": "节点 6",
"ParentID": 5,
"Children": [
{
"ID": 7,
"Name": "节点 7",
"ParentID": 6,
"Children": null
}
]
}
]
}
]
可以看到,生成了一棵带有子节点的树状结构。
- 处理动态节点数组
假设节点数组是动态的,需要从数据库或者其他来源获取。可以通过 GORM 库从数据库获取节点数据。
type TreeNode struct {
ID uint `gorm:"primary_key;auto_increment" json:"id"`
Name string `gorm:"type:varchar(100)" json:"name"`
ParentID uint `gorm:"index" json:"parent_id"`
}
func GetTreeData() []*Node {
var treeData []*TreeNode
db.Find(&treeData)
var data []*Node
for _, v := range treeData {
data = append(data, &Node{
ID: v.ID,
Name: v.Name,
ParentID: int(v.ParentID),
})
}
return data
}
然后调用 GetTreeData
函数获取动态节点数据,再传入 buildTree
函数生成树状结构。
treeData := GetTreeData()
tree := buildTree(0, treeData)
treeJSON, err := json.Marshal(tree)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(treeJSON))
这样,就可以根据动态节点数组生成树状结构了。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:golang通过递归遍历生成树状结构的操作 - Python技术站