英文:
Convert map to tree in Go
问题
我有一个非常具体的问题,我无法找到解决方案。
我有一个map[string]Metric
,我想将其转换为树形结构,以便在前端中使用。Metric
接口具有Path()
和Name()
方法,Name()
方法返回以句点分隔的路径的最后一部分(因此路径为'my.awesome.metric'意味着该指标的名称为'metric')。
树应该按路径排序,并且应该包含IndexNode
。该结构的定义如下:
type IndexNode struct {
Name string
Path string
Children []*IndexNode
}
因此,像这样的映射:
{
my.awesome.metric.downloads
my.awesome.othermetric.downloads
my.awesome.othermetric.uploads
my.other.cool.metric
}
应该生成如下的树形结构:(对于粗糙的ASCII艺术表示我表示抱歉)
+-- other -- cool -- metric
|
my --+ +-- metric -- downloads
| |
+-- awesome --+ +-- downloads
| |
+-- othermetric --+
|
+-- uploads
请注意,我只有一个根节点(在本例中为'my')。树中的顺序对我来说并不重要。
我已经尽力了,但无法解决它... 在大量搜索之后(只显示了如何创建二叉搜索树和GoDS库),我决定在这里提出我的第一个问题 😊
谢谢你的帮助!
英文:
I have a very specific problem, I cannot figure out a solution for.
I have a map[string]Metric
, which I want to convert into a tree for using in a frontend. The Metric
interface looks has a Path()
and a Name()
Method, the name method returns the last part of a period-separated path (so a path of 'my.awesome.metric' will mean that this metric has the name 'metric')
The tree should be sorted by the path and should contain IndexNode
s. This struct looks like this:
type IndexNode struct {
Name string
Path string
Children []*IndexNode
}
So a map like this:
{
my.awesome.metric.downloads
my.awesome.othermetric.downloads
my.awesome.othermetric.uploads
my.other.cool.metric
}
Should lead to a tree like this: (sorry for the crude ascii art)
+-- other -- cool -- metric
|
my --+ +-- metric -- downloads
| |
+-- awesome --+ +-- downloads
| |
+-- othermetric --+
|
+-- uploads
Note that I only ever have one root node (my in this case). The order inside of the tree does not matter to me.
I tried my best and cannot figure it out... After lots of googleing (which only showed me how to create binary search trees and the GoDS library), I resigned and decided to ask my very first question here 😊
Thanks for your help!
答案1
得分: 1
将Children
更改为map[string]*IndexNode
,你就完成了一半的工作。如果你不介意查找速度变慢,你可以使用切片,但这意味着你需要每次遍历树时在切片中搜索所需的子节点。在这种情况下,使用map更快更容易。
现在,你只需要编写一个递归函数,沿着树向下移动,根据路径中的每个元素创建所需的节点,直到到达末尾。
不幸的是,我无法立即访问示例,因为我的所有代码都在另一台电脑上
以下是一个简单的示例:
type Tree struct {
Parent *Tree
Children map[string]*Tree
Payload bool // 在这里放入你的数据
}
func NewTree(parent *Tree, path []string, payload bool) *Tree {
if parent == nil {
parent = &Tree{nil, map[string]*Tree{}, false}
}
if len(path) == 0 {
parent.Payload = payload
return parent
}
child := parent.Children[path[0]]
if child == nil {
child = &Tree{parent, map[string]*Tree{}, false}
parent.Children[path[0]] = child
}
return NewTree(child, path[1:], payload)
}
用法:
root := NewTree(nil, nil, false)
newnode := NewTree(root, []string{"A", "B", "C"}, true)
英文:
Change Children
to map[string]*IndexNode
and you are halfway there. If you don't mind it being a lot slower to look stuff up, you can use a slice, but this means you need to search the slice to find the child you want every time you traverse the tree. A map is faster and easier in this case.
Now you just need to write a recursive function that steps down the tree, making nodes as needed for each element in the path until it reaches the end.
Unfortunately I don't have ready access to an example, all my code in on my other computer
A quick and dirty example:
type Tree struct {
Parent *Tree
Children map[string]*Tree
Payload bool // Your data here
}
func NewTree(parent *Tree, path []string, payload bool) *Tree {
if parent == nil {
parent = &Tree{nil, map[string]*Tree{}, false}
}
if len(path) == 0 {
parent.Payload = payload
return parent
}
child := parent.Children[path[0]]
if child == nil {
child = &Tree{parent, map[string]*Tree{}, false}
parent.Children[path[0]] = child
}
return NewTree(child, path[1:], payload)
}
Usage:
root := NewTree(nil, nil, false)
newnode := NewTree(root, []string{"A", "B", "C"}, true)
答案2
得分: 0
这是使用映射的解决方案,遍历它可以帮助你填充数据结构。可以在树形导航中的"Parent xxx Child xxx"处创建节点。链接:https://play.golang.org/p/sVqBCVgiBG
英文:
Here's a solution using a map, traversing it can help you populate the data structure. Can create the nodes where it says "Parent xxx Child xxx" in the tree navigation https://play.golang.org/p/sVqBCVgiBG
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论