You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go中从map生成父子层级的JSON格式树结构

解决方案

1. 修复结构体定义

你原有结构体的字段首字母为小写,属于Go语言的未导出字段,json序列化时会被直接忽略,同时字段名也不符合预期输出的格式,需要修改为:

type Nodes struct {
    Funcname string   `json:"Funcname"`
    Nodes    []*Nodes `json:"Nodes"`
}

2. 核心构建逻辑

整个构建流程时间复杂度为O(n),适配大数据量、多层级场景,不会出现递归栈溢出问题:

  • 第一步:找根节点:所有从未作为子节点出现的key就是根节点(常规业务场景下仅有一个根)
  • 第二步:创建所有节点的缓存映射,避免重复实例化节点,提升处理效率
  • 第三步:遍历原map,给每个父节点绑定对应的子节点列表

3. 完整可运行代码

package main

import (
	"encoding/json"
	"log"
)

type Nodes struct {
	Funcname string   `json:"Funcname"`
	Nodes    []*Nodes `json:"Nodes"`
}

func main() {
	var m map[string][]string
	m = make(map[string][]string)
	// 父节点为key,对应子节点列表为value
	m["root_node"] = []string{"1", "2", "3", "4"}
	m["1"] = []string{"5", "6"}
	m["2"] = []string{"7"}
	m["3"] = []string{"8", "9"}
	m["5"] = []string{"10"}
	m["7"] = []string{"11"}
	m["8"] = []string{"12", "13"}

	// 1. 收集所有子节点,筛选根节点
	childSet := make(map[string]struct{})
	for _, children := range m {
		for _, child := range children {
			childSet[child] = struct{}{}
		}
	}
	// 根节点特征:不存在于子节点集合中
	var root *Nodes
	nodeCache := make(map[string]*Nodes)
	for parent := range m {
		if _, ok := childSet[parent]; !ok {
			root = &Nodes{Funcname: parent}
			nodeCache[parent] = root
			break
		}
	}

	// 2. 初始化所有节点存入缓存,避免重复创建
	for parent, children := range m {
		if _, ok := nodeCache[parent]; !ok {
			nodeCache[parent] = &Nodes{Funcname: parent}
		}
		for _, child := range children {
			if _, ok := nodeCache[child]; !ok {
				nodeCache[child] = &Nodes{Funcname: child}
			}
		}
	}

	// 3. 绑定父子节点关系
	for parent, children := range m {
		pNode := nodeCache[parent]
		for _, child := range children {
			cNode := nodeCache[child]
			pNode.Nodes = append(pNode.Nodes, cNode)
		}
	}

	// 序列化输出,MarshalIndent用于生成格式化的JSON,和你预期的格式完全匹配
	bytes, err := json.MarshalIndent(root, "", "   ")
	if err != nil {
		log.Fatal(err)
	}
	log.Println(string(bytes))
}

4. 关于是否需要补充信息的说明

只要你的输入map满足以下条件,就不需要补充额外信息:

  • 不存在环形引用(比如A的子节点是B,B的子节点是A)
  • 仅有一个根节点(如果是多根场景,自行指定需要输出的根节点即可)
  • 所有子节点都能在map中找到对应关系(如果存在孤立子节点,可根据业务需求决定是否要挂载到默认根节点下)

内容的提问来源于stack exchange,提问作者user248396

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 07:12:04