为了账号安全,请及时绑定邮箱和手机立即绑定

如何从地图生成 json 格式的树(父子级)

如何从地图生成 json 格式的树(父子级)

Go
天涯尽头无女友 2022-09-12 20:32:52
我想要什么?从地图中获取 JSON 格式的树。要使用的数据:映射(键值对),将键作为父项,以各自的值作为子项法典:下面的代码使用示例数据,我想稍后使用大数据意味着有更多的父子。如何从地图构建父子级?如果我需要任何其他信息来将地图数据解析为树结构,请告诉我?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 achievedbytes, 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      }   ]}
查看完整描述

2 回答

?
倚天杖

TA贡献1828条经验 获得超3个赞

更简单的方法

我们也可以说这是更简洁的方法,用构造函数语法构造节点。


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))

}


查看完整回答
反对 回复 2022-09-12
?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

首先用方法定义一个类型 -NodeAddChild()


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)

}


查看完整回答
反对 回复 2022-09-12
  • 2 回答
  • 0 关注
  • 154 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号