How to create a infinite nested json and access the same in go lang data structures,
For example below is the sample json with 3 levels, in general it should be dynamic, user can add any children by selecting the value from the dropdown which is populated tree like dropdown on UI.
{
"value": {
"Id": "1",
"Text": "abcd",
"Parent": ""
},
"children": [
{
"value": {
"Id": "2",
"Text": "abcd",
"Parent": "1"
},
"children": [
{
"value": {
"Id": "3",
"Text": "abcd",
"Parent": "1"
}
}
]
}
]
}
structures in go: I have created this go data structure but it will access only upto 3 levels based on the above json, can we make this data structure as dynamic where it should handle infinite nested 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"`
}
Note: we can add n number of parents and n number of children, is this possible in Go data structures?
can you suggest best and easy way to implement this?
How can we add/delete/edit any parent or child? (The above json example will come from UI) ? To add/delete/edit any parent or child which json structure or id needed?
You can use recursive structures in Go to represent this json (by recursive, I mean that Level
contains a []Level
):
type Value struct {
ID string
Text string
Parent string
}
type Level struct {
Value Value `json:"value"`
Children []Level
}
Given the json you listed as the string j
, I can now unmarshal it as follows:
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])
This outputs:
{{1 abcd } [{{2 abcd 1} [{{3 abcd 1} []}]}]}
{{2 abcd 1} [{{3 abcd 1} []}]}
{{3 abcd 1} []}
Addition to @marc, you can combine these two struct Value
& Level
in a single structure. Like AutoGenerated one, you only need to use [ ]Level as Children.
type Level struct {
Value struct {
ID string
Text string
Parent string
} `json:"value"`
Children []Level
}
See in playground
Based on @Marc's data structure, a simple 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)
}
Remove and modify would be mostly the same.
Playground: https://play.golang.org/p/7sWRJ-9EQSv