I am evaluating Go to replace Node.js infrastructure and I am not sure how to create a structure to represent a N-ary tree.
In JavaScript, I parse a file to build up a hierarchy of geographic locations of arbitrary depth. Here is an example:
{
'country1': {
'area1': {
'town1': {},
'town2': {}
},
'area2': {
'town3': {}
}
}
}
Towns could expand into specific roads and so on. The hierarchy doesn't have a fixed depth.
How can I create an equivalent structure in Go?
If you're going to have arbitrary depth, then it might be worth it to create a default struct that can be nested:
type area struct {
Name string
//Any other area info
Sections []*area
}
Slices of pointers aren't initialized when creating a new struct object, so it's a valid construct. Declare a.Sections = new([]*area)
and append area
pointers to it. You will have len(a.Sections)
or a for range
loop for use in the tree traversal.
Parsing and traversal would be coded recursively, so you would need a type identifier if you treat different areas in different ways.
Let's review the hierarchy.
At the top level, you map country names to country objects.
Each country object maps area names to area objects.
Each area object maps town names to town objects.
In Go, you can implement each level of the hierarchy as a map[string]*Something
, with the last level consisting of Town
objects that contain various information about towns:
type Country map[string]*Area
type Area map[string]*Town
type Town struct {
Name string
Population int
Latitude, Longitude float64
}
The sample hierarchy that you've given in your question would then look like this:
countries := map[string]*Country{
"country1": &Country{
"area1": &Area{
"town1": &Town{},
"town2": &Town{},
},
"area2": &Area{
"town3": &Town{},
},
},
}
If you don't want to map to concrete types, you can use map[string]interface{}
, but then you'll need type assertions to work with the values. Here is a code sample taken from Zack Bloom's article on Go and JSON:
var parsed map[string]interface{}
data := []byte(`
{
"id": "k34rAT4",
"age": 24
}
`)
err := json.Unmarshal(data, &parsed)
idString := parsed["id"].(string)