英文:
N-ary tree in Go
问题
我正在评估使用Go替代Node.js基础架构,并且我不确定如何创建表示N叉树的结构。
在JavaScript中,我解析一个文件来构建任意深度的地理位置层次结构。这是一个示例:
{
'country1': {
'area1': {
'town1': {},
'town2': {}
},
'area2': {
'town3': {}
}
}
}
城镇可以扩展到具体的道路等。层次结构没有固定的深度。
我该如何在Go中创建一个等效的结构?
英文:
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?
答案1
得分: 3
如果你要有任意深度的结构,那么创建一个可以嵌套的默认结构可能是值得的:
type area struct {
Name string
// 其他区域信息
Sections []*area
}
在创建新的结构对象时,指针切片不会被初始化,所以这是一个有效的构造方式。声明 a.Sections = new([]*area)
并将 area
的指针追加到其中。你可以使用 len(a.Sections)
或 for range
循环来进行树遍历。
解析和遍历可以使用递归编码,所以如果你以不同的方式处理不同的区域,你将需要一个类型标识符。
英文:
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.
答案2
得分: 2
让我们来回顾一下这个层次结构。
-
在顶层,你将国家名称映射到国家对象。
-
每个国家对象将区域名称映射到区域对象。
-
每个区域对象将城镇名称映射到城镇对象。
在Go语言中,你可以将层次结构的每个级别实现为map[string]*Something
,其中最后一级由包含有关城镇的各种信息的Town
对象组成:
type Country map[string]*Area
type Area map[string]*Town
type Town struct {
Name string
Population int
Latitude, Longitude float64
}
你在问题中给出的示例层次结构将如下所示:
countries := map[string]*Country{
"country1": &Country{
"area1": &Area{
"town1": &Town{},
"town2": &Town{},
},
"area2": &Area{
"town3": &Town{},
},
},
}
如果你不想映射到具体类型,可以使用map[string]interface{}
,但是你将需要使用类型断言来处理值。以下是从Zack Bloom的关于Go和JSON的文章中摘取的代码示例:
var parsed map[string]interface{}
data := []byte(`
{
"id": "k34rAT4",
"age": 24
}
`)
err := json.Unmarshal(data, &parsed)
idString := parsed["id"].(string)
英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论