英文:
How to generate a tree (parent-child) in json format from a map
问题
我明白了,你想要将一个Map转换为JSON格式的树结构。以下是你提供的代码的翻译结果:
type Nodes struct {
Funcname string
Nodes []*Nodes
}
func main() {
var m map[string][]string
m = make(map[string][]string)
// 父节点(key)和子节点(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格式
root_node := &Nodes{
Funcname: "root_node",
Nodes: buildTree("root_node", m),
}
// 将树结构转换为JSON格式
bytes, err := json.Marshal(root_node)
if err != nil {
log.Fatal(err)
}
}
// 递归构建树结构
func buildTree(node string, m map[string][]string) []*Nodes {
children, ok := m[node]
if !ok {
return nil
}
nodes := make([]*Nodes, len(children))
for i, child := range children {
nodes[i] = &Nodes{
Funcname: child,
Nodes: buildTree(child, m),
}
}
return nodes
}
期望的JSON格式如下所示:
{
"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
}
]
}
希望能对你有所帮助!如果你需要进一步的解释或有其他问题,请随时提问。
英文:
What do I want?
To get a tree in JSON format from a Map.
Data to be used:
A map (key-value pairs), having keys as parents and their respective values as children
Code:
The following code uses sample data, I want to use big data later on means having more parents-children. How can I structure parent-child from a Map? Please let me know if I need any other information to parse Map data into a tree structure?
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)
}
}
My expectation:
{
"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
}
]
}
答案1
得分: 1
更简单的方法
我们还可以说,使用构造函数语法构建节点是一种更清晰的方法。
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))
}
英文:
easier approach
We can also say that it is cleaner approach, to construct nodes with constructor syntax.
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))
}
harder approach
The output is the same but its lot more dynamic and allows you to store additional values, On the other hand traversing the tree is lot more annoying as you have to always cast everything.
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))
}
output
{"Name":"1","Children":[{"Name":"3","Children":[{"Name":"5","Children":null}]}]} // #1
{"Children":[{"Children":[{"Name":"5"}],"Name":"3"}],"Name":"1"} // #2
edit
In addition here is the function to insert a node to the structure. False is returned if operation fails.
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))
}
答案2
得分: 0
首先定义一个具有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从给定的映射生成树,并返回指向树根节点的指针。
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。
英文:
First define a Node
type with AddChild()
method -
type Node struct {
Fn string `json:"Funcname"`
Children []*Node `json:"Nodes"`
}
func (node *Node) AddChild(child *Node) {
node.Children = append(node.Children, child)
}
A constructor function to construct a new node for given fn
-
func CreateNewNode(fn string) *Node {
newNode := new(Node)
newNode.Fn = fn
return newNode
}
To generate a tree from map define MakeTreeFromMap()
function as follows -
// 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]
}
Serialize tree into JSON -
root_node := MakeTreeFromMap(m, "root_node")
bytes, err := json.Marshal(root_node)
if err != nil {
log.Fatal(err)
}
See Go Playground for full working example.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论