我有一个非常具体的问题,我无法找到解决方案。
我有一个map[string]Metric
,我希望将其转换为树,以便在前端使用。 Metric
接口看起来有一个Path()
和一个Name()
方法,name方法返回一个以句点分隔的路径的最后一部分(所以路径为' my.awesome。指标'表示此指标的名称为' metric')
树应按路径排序,并应包含IndexNode
s。这个结构如下所示:
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)。树内的顺序对我来说无关紧要。
我尽我所能,无法弄明白...经过大量的googleing(只向我展示了如何创建二元搜索树和GoDS库),我辞职并决定在这里问我的第一个问题
感谢您的帮助!
答案 0 :(得分:0)
将Children
更改为map[string]*IndexNode
,您就在那里。如果你不介意看起来很慢,你可以使用切片,但这意味着你需要搜索切片,以便在每次遍历树时找到你想要的孩子。在这种情况下,地图更快更容易。
现在你只需要编写一个递归函数来逐步降低树,根据需要为路径中的每个元素创建节点,直到它到达终点。
不幸的是,我没有准备好访问我的另一台计算机上的所有代码示例:(
一个快速而又肮脏的例子:
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)
}
用法:
root := NewTree(nil, nil, false)
newnode := NewTree(root, []string{"A", "B", "C"}, true)
答案 1 :(得分:0)
这是使用地图的解决方案,遍历它可以帮助您填充数据结构。可以在树导航https://play.golang.org/p/sVqBCVgiBG
中创建“Parent xxx Child xxx”的节点