如何在go lang数据结构中创建无限嵌套json并访问它?

时间:2018-02-01 11:43:47

标签: json go data-structures

如何在go lang数据结构中创建无限嵌套json并访问它,

例如下面是具有3个级别的示例json,通常它应该是动态的,用户可以通过从下拉列表中选择值来添加任何子项,该下拉列表是填充树,如UI上的下拉列表。

{
        "value": {
            "Id": "1",
            "Text": "abcd",
            "Parent": ""
        },
        "children": [
            {
                "value": {
                    "Id": "2",
                    "Text": "abcd",
                    "Parent": "1"
                },
                "children": [
                    {
                        "value": {
                            "Id": "3",
                            "Text": "abcd",
                            "Parent": "1"
                        }
                    }
                ]
            }
        ]
    }
go中的

结构:我创建了这个go数据结构,但是基于上面的json,它只能访问最多3个级别,我们可以将这个数据结构设置为动态的,它应该处理无限的嵌套json。

 type AutoGenerated struct {
        Value struct {
            ID     string `json:"Id"`
            Text   string `json:"Text"`
            Parent string `json:"Parent"`
        } `json:"value"`
        Children []struct {
            Value struct {
                ID     string `json:"Id"`
                Text   string `json:"Text"`
                Parent string `json:"Parent"`
            } `json:"value"`
            Children []struct {
                Value struct {
                    ID     string `json:"Id"`
                    Text   string `json:"Text"`
                    Parent string `json:"Parent"`
                } `json:"value"`
            } `json:"children"`
        } `json:"children"`
    }

注意:我们可以添加n个父项和n个子项,这在Go数据结构中是否可行?

你能建议最好和最简单的方法来实现这个吗?

我们如何添加/删除/编辑任何父母或子女? (上面的json示例将来自UI)?添加/删除/编辑所需的json结构或id的父或子?

3 个答案:

答案 0 :(得分:3)

你可以在Go中使用递归结构来表示这个json(通过递归,我的意思是Level包含[]Level):

type Value struct {
    ID     string
    Text   string
    Parent string
}

type Level struct {
    Value    Value `json:"value"`
    Children []Level
}

鉴于您列为字符串j的json,我现在可以按如下方式解组它:

var root Level
err := json.Unmarshal([]byte(j), &root)
if err != nil {
    panic(err)
}
fmt.Println(root)
fmt.Println(root.Children[0])
fmt.Println(root.Children[0].Children[0])

输出:

{{1 abcd } [{{2 abcd 1} [{{3 abcd 1} []}]}]}
{{2 abcd 1} [{{3 abcd 1} []}]}
{{3 abcd 1} []}

Go playground link

答案 1 :(得分:0)

除了@marc,你可以将这两个结构Value和&结合起来。 Level在一个结构中。与AutoGenerated一样,您只需要使用[] Level as Children。

type Level struct {
    Value struct {
        ID     string
        Text   string
        Parent string
    } `json:"value"`
    Children []Level
}

参见 playground

答案 2 :(得分:0)

基于@ Marc的数据结构,简单add

func (l *Level) Add(path,Id,Text string) error {
    if path=="" {
        l.Children = append(l.Children, Level{ Value: Value{Id,Text,l.Value.ID} })
        return nil
    }
    x:=strings.SplitN(path,".",2)
    name,remain:=x[0],""
    if len(x)>1 {
        remain = x[1]
    }

    for i:=range l.Children {
        if l.Children[i].Value.ID == name {
            return l.Children[i].Add(remain,Id,Text)
        }
    }
    return errors.New("Not found")
}

func main() {
    var root Level
    err := json.Unmarshal([]byte(j), &root)
    if err != nil {
        panic(err)
    }
    fmt.Println(root)
    fmt.Println(root.Children[0])
    fmt.Println(root.Children[0].Children[0])
    fmt.Println(root.Add("2.3","4","xxx"))
    fmt.Println(root)
}

删除和修改大致相同。

游乐场:https://play.golang.org/p/7sWRJ-9EQSv