如何从地图生成 json 格式的树(父子)
How to generate a tree (parent-child) in json format from a map
我想要什么?
从地图中获取 JSON 格式的树。
要使用的数据:
一个映射(键值对),键作为父项,它们各自的值作为子项
代码:
以下代码使用示例数据,我想稍后使用大数据意味着有更多的父子。如何从 Map 构建父子关系?如果我需要任何其他信息来将地图数据解析为树结构,请告诉我?
type Nodes struct {
fn string
children []*Nodes
}
func main() {
var m map[string][]string
m = make(map[string][]string)
//map of parents(key) and child(values)
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"}
//json format: I don't know how to get root_node so expected result can be achieved
bytes, err := json.Marshal(root_node)
if err != nil {
log.Fatal(err)
}
}
我的期望:
{
"Funcname": "root_node",
"Nodes": [
{
"Funcname": "1",
"Nodes": [
{
"Funcname": "5",
"Nodes": [
{
"Funcname": "10",
"Nodes": null
}
]
},
{
"Funcname": "6",
"Nodes": null
}
]
},
{
"Funcname": "2",
"Nodes": [
{
"Funcname": "7",
"Nodes": [
{
"Funcname": "11",
"Nodes": null
}
]
}
]
},
{
"Funcname": "3",
"Nodes": [
{
"Funcname": "8",
"Nodes": [
{
"Funcname": "12",
"Nodes": null
},
{
"Funcname": "13",
"Nodes": null
}
]
},
{
"Funcname": "9",
"Nodes": null
}
]
},
{
"Funcname": "4",
"Nodes": null
}
]
}
更简单的方法
我们也可以说这是一种更简洁的方法,使用构造函数语法构造节点。
type Node struct {
Name string
Children []*Node
}
func first_example() {
root := Node{
Name: "1",
Children: []*Node{
{
Name: "3",
Children: []*Node{
{
Name: "5",
},
},
},
},
}
bytes, err := json.Marshal(root)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}
更难的方法
输出是相同的,但它更加动态,并且允许您存储额外的值,另一方面,遍历树更烦人,因为您必须始终转换所有内容。
func second_example() {
root := map[string]interface{}{
"Name": "1",
"Children": []map[string]interface{}{
{
"Name": "3",
"Children": []map[string]interface{}{
{
"Name": "5",
},
},
},
},
}
bytes, err := json.Marshal(root)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}
输出
{"Name":"1","Children":[{"Name":"3","Children":[{"Name":"5","Children":null}]}]} // #1
{"Children":[{"Children":[{"Name":"5"}],"Name":"3"}],"Name":"1"} // #2
编辑
此外,这里还有向结构中插入节点的功能。操作失败返回false
func (n *Node) InsertNode(path string, o *Node) bool {
parts := strings.Split(path, " ")
target := n
for _, part := range parts {
found := false
for _, child := range target.Children {
if child.Name == part {
target = child
found = true
break
}
}
if !found {
return false
}
}
target.Children = append(target.Children, o)
return true
}
func third_example() {
root := &Node{Name: "1"}
root.Children = append(root.Children, &Node{Name: "3"})
root.InsertNode("3", &Node{Name: "5"})
bytes, err := json.Marshal(root)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}
先用AddChild()
方法定义一个Node
类型-
type Node struct {
Fn string `json:"Funcname"`
Children []*Node `json:"Nodes"`
}
func (node *Node) AddChild(child *Node) {
node.Children = append(node.Children, child)
}
为给定 fn
-
构造新节点的构造函数
func CreateNewNode(fn string) *Node {
newNode := new(Node)
newNode.Fn = fn
return newNode
}
要从地图生成树,定义 MakeTreeFromMap()
函数如下 -
// MakeTreeFromMap generates a tree from given map and returns pointer to root node of tree.
func MakeTreeFromMap(treeMap map[string][]string, rootNodeFn string) *Node {
cache := make(map[string]*Node)
for fn, children := range treeMap {
if _, nodeExists := cache[fn]; !nodeExists {
node := CreateNewNode(fn)
cache[fn] = node
}
for _, childFn := range children {
if _, childExists := cache[childFn]; !childExists {
child := CreateNewNode(childFn)
cache[childFn] = child
}
cache[fn].AddChild(cache[childFn])
}
}
return cache[rootNodeFn]
}
将树序列化为JSON-
root_node := MakeTreeFromMap(m, "root_node")
bytes, err := json.Marshal(root_node)
if err != nil {
log.Fatal(err)
}
有关完整的工作示例,请参阅 Go Playground。
我想要什么?
从地图中获取 JSON 格式的树。
要使用的数据:
一个映射(键值对),键作为父项,它们各自的值作为子项
代码: 以下代码使用示例数据,我想稍后使用大数据意味着有更多的父子。如何从 Map 构建父子关系?如果我需要任何其他信息来将地图数据解析为树结构,请告诉我?
type Nodes struct {
fn string
children []*Nodes
}
func main() {
var m map[string][]string
m = make(map[string][]string)
//map of parents(key) and child(values)
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"}
//json format: I don't know how to get root_node so expected result can be achieved
bytes, err := json.Marshal(root_node)
if err != nil {
log.Fatal(err)
}
}
我的期望:
{
"Funcname": "root_node",
"Nodes": [
{
"Funcname": "1",
"Nodes": [
{
"Funcname": "5",
"Nodes": [
{
"Funcname": "10",
"Nodes": null
}
]
},
{
"Funcname": "6",
"Nodes": null
}
]
},
{
"Funcname": "2",
"Nodes": [
{
"Funcname": "7",
"Nodes": [
{
"Funcname": "11",
"Nodes": null
}
]
}
]
},
{
"Funcname": "3",
"Nodes": [
{
"Funcname": "8",
"Nodes": [
{
"Funcname": "12",
"Nodes": null
},
{
"Funcname": "13",
"Nodes": null
}
]
},
{
"Funcname": "9",
"Nodes": null
}
]
},
{
"Funcname": "4",
"Nodes": null
}
]
}
更简单的方法
我们也可以说这是一种更简洁的方法,使用构造函数语法构造节点。
type Node struct {
Name string
Children []*Node
}
func first_example() {
root := Node{
Name: "1",
Children: []*Node{
{
Name: "3",
Children: []*Node{
{
Name: "5",
},
},
},
},
}
bytes, err := json.Marshal(root)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}
更难的方法
输出是相同的,但它更加动态,并且允许您存储额外的值,另一方面,遍历树更烦人,因为您必须始终转换所有内容。
func second_example() {
root := map[string]interface{}{
"Name": "1",
"Children": []map[string]interface{}{
{
"Name": "3",
"Children": []map[string]interface{}{
{
"Name": "5",
},
},
},
},
}
bytes, err := json.Marshal(root)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}
输出
{"Name":"1","Children":[{"Name":"3","Children":[{"Name":"5","Children":null}]}]} // #1
{"Children":[{"Children":[{"Name":"5"}],"Name":"3"}],"Name":"1"} // #2
编辑
此外,这里还有向结构中插入节点的功能。操作失败返回false
func (n *Node) InsertNode(path string, o *Node) bool {
parts := strings.Split(path, " ")
target := n
for _, part := range parts {
found := false
for _, child := range target.Children {
if child.Name == part {
target = child
found = true
break
}
}
if !found {
return false
}
}
target.Children = append(target.Children, o)
return true
}
func third_example() {
root := &Node{Name: "1"}
root.Children = append(root.Children, &Node{Name: "3"})
root.InsertNode("3", &Node{Name: "5"})
bytes, err := json.Marshal(root)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}
先用AddChild()
方法定义一个Node
类型-
type Node struct {
Fn string `json:"Funcname"`
Children []*Node `json:"Nodes"`
}
func (node *Node) AddChild(child *Node) {
node.Children = append(node.Children, child)
}
为给定 fn
-
func CreateNewNode(fn string) *Node {
newNode := new(Node)
newNode.Fn = fn
return newNode
}
要从地图生成树,定义 MakeTreeFromMap()
函数如下 -
// MakeTreeFromMap generates a tree from given map and returns pointer to root node of tree.
func MakeTreeFromMap(treeMap map[string][]string, rootNodeFn string) *Node {
cache := make(map[string]*Node)
for fn, children := range treeMap {
if _, nodeExists := cache[fn]; !nodeExists {
node := CreateNewNode(fn)
cache[fn] = node
}
for _, childFn := range children {
if _, childExists := cache[childFn]; !childExists {
child := CreateNewNode(childFn)
cache[childFn] = child
}
cache[fn].AddChild(cache[childFn])
}
}
return cache[rootNodeFn]
}
将树序列化为JSON-
root_node := MakeTreeFromMap(m, "root_node")
bytes, err := json.Marshal(root_node)
if err != nil {
log.Fatal(err)
}
有关完整的工作示例,请参阅 Go Playground。