golang通过递归遍历生成树状结构的操作

下面是详细讲解 golang 通过递归遍历生成树状结构的操作的完整攻略。

操作步骤

  1. 定义节点结构体

首先需要定义节点结构体,表示每一个节点的信息。

type Node struct {
    ID       int       // 节点 ID
    Name     string    // 节点名称
    ParentID int       // 父节点 ID
    Children []*Node   // 子节点
}
  1. 创建节点数组

创建一个节点数组,用于存储所有节点信息。

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},
}
  1. 定义递归函数

定义一个递归函数 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。如果等于,表示当前节点为传入节点的子节点,需要继续往下递归。

  1. 生成树状结构

调用 buildTree 函数,传入根节点的父节点 ID 和包含所有节点信息的数组 treeData,即可生成树状结构。

tree := buildTree(0, treeData)
  1. 输出结果

最后,使用 json.Marshal 将生成的树状结构转换为 JSON 格式并输出。

treeJSON, err := json.Marshal(tree)
if err != nil {
    fmt.Println(err)
}
fmt.Println(string(treeJSON))

示例说明

  1. 根据节点数组生成树状结构

假设有以下节点数组:

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

可以看到,生成了一棵带有子节点的树状结构。

  1. 处理动态节点数组

假设节点数组是动态的,需要从数据库或者其他来源获取。可以通过 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技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 详解基于Android App 安全登录认证解决方案

    详解基于Android App 安全登录认证解决方案 简介 在安卓应用的开发过程中,用户登录认证是很重要的一环。为了保证用户的安全性和数据的保密性,我们需要考虑一种安全的登录认证解决方案。本文将详细介绍基于Android App的安全登录认证解决方案,包括常见的攻击方式,安全措施和单点登录等内容。 常见的攻击方式 在介绍登录认证解决方案之前,首先需要了解一些…

    other 2023年6月26日
    00
  • Windows 11系统怎么修改用户名密码? win11更改账户密码的多种方法

    以下是“Windows 11系统怎么修改用户名密码? win11更改账户密码的多种方法”的完整攻略。 方法一:使用系统设置更改密码 打开“设置”应用,点击左侧菜单栏中的“帐户”选项。 在右侧的“帐户信息”窗口中,找到“登录选项”下的“更改密码”链接,点击进入。 在弹出的“更改您的密码”窗口中,输入当前账户的密码,并输入新密码,确认新密码后点击“下一步”按钮。…

    other 2023年6月27日
    00
  • linux上pem格式私钥转pfx格式证书的命令

    Linux上PEM格式私钥转PFX格式证书的命令 在Linux系统中,常常使用openssl命令来生成或转换各种格式的证书和私钥。本文将介绍如何将PEM格式的私钥转换为PFX格式的证书。 什么是PEM格式和PFX格式? PEM格式是一种加密文件格式,用于存储证书及其相关的私钥和公钥。PEM格式通常以“—–BEGIN PRIVATE KEY—–” …

    其他 2023年3月28日
    00
  • 浅谈在Vue-cli里基于axios封装复用请求

    下面是详细的讲解。 1. 前言 在Vue.js中,使用axios作为HTTP客户端发起请求已经成为很普遍的做法。而Vue-cli是一个著名的脚手架工具,提供了一个使用webpack来构建Vue.js项目的简洁CLI。Vue-cli在项目初始化过程中会使用axios模块。但是当我们需要为项目提供更好的API调用封装和复用能力时,我们需要在Vue-cli的基础上…

    other 2023年6月25日
    00
  • windows使用docker运行mysql等工具(一)windows安装docker

    Windows使用Docker运行MySQL等工具(一)Windows安装Docker 作为一种开源的容器化平台,Docker最初是为Linux系统设计的,但随着它的发展,它的支持已经扩展到了Windows和MacOS系统。在Windows操作系统上安装和使用Docker可以帮助我们更加便捷、快速地搭建各种环境,包括MySQL数据库等常用工具。 为什么要使用…

    其他 2023年3月29日
    00
  • C++内存模型和名称空间详解

    C++内存模型和名称空间详解 什么是内存模型? 内存模型是描述计算机在执行程序时如何处理内存的理论模型。C++语言的内存模型是一个抽象的模型,用于描述在C++程序中内存如何被组织和访问的规则和约束。 C++内存模型对于程序员来说非常重要,因为它决定了C++代码在计算机上的运行方式,可以帮助我们更好地理解程序的行为和优化程序的性能。 在C++中,内存空间可以被…

    other 2023年6月20日
    00
  • asp之字符串操作函数

    ASP之字符串操作函数 在ASP中,字符串操作是很常用的操作,在字符串处理中有很多字符串操作函数可供使用。掌握这些函数的使用可以方便我们对字符串进行处理。 常用的字符串操作函数 Len函数 Len函数返回字符串的长度。 语法: Len(string) 参数: string:指定要获取长度的字符串。 示例: <% Dim str str = "…

    other 2023年6月20日
    00
  • BAT脚本批量修改文件名的两种方法

    下面是详细讲解“BAT脚本批量修改文件名的两种方法”的完整攻略。 1. 前言 在日常电脑使用过程中,我们经常需要批量修改文件名。传统的方式是手动一个一个修改,这样既费时又容易出错。而使用BAT脚本批量修改则可以省去人工操作,提高效率。 本文将介绍两种利用BAT脚本批量修改文件名的方法,分别是使用“for”循环和使用“ren”命令。 2. 使用“for”循环 …

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部