这是一个古老的“为什么我的地图打印乱序”问题的变种。有没有简单的方法来遍历地图?
我有一个(相当大量)地图map[MyKey]MyValue
,其中MyKey
和MyValue
是(通常)结构。我对所有关键类型都有“少”的功能。
我需要按顺序遍历地图。 (具体而言,为了通过该类型较少函数中定义)现在,我的代码如下所示:
type PairKeyValue struct {
MyKey
MyValue
}
type PairKeyValueSlice []Pair
func (ps PairKeyValueSlice) Len() int {
return len(ps)
}
func (ps PairKeyValueSlice) Swap(i,j int) {
ps[i], ps[j] = ps[j], ps[i]
}
func (ps PairKeyValueSlice) Less(i,j int) {
return LessKey(ps[i].MyKey, ps[j].MyKey)
}
func NewPairKeyValueSlice(m map[MyKey]MyValue) (ps PairKeyValueSlice) {
ps = make(PairKeyValueSlice, len(m))
i := 0
for k,v := range m {
ps[i] = PairKeyValue{k,v}
i++
}
sort.Sort(ps)
}
然后,任何时候我想要一个有序的迭代,它看起来像:
var m map[MyKey]MyValue
m = GetMapFromSomewhereUseful()
for _, kv := range NewPairKeyValueSlice(m) {
key := kv.MyKey
value := kv.MyValue
DoUsefulWork(key, value)
}
而这似乎很大程度上工作。问题在于它非常冗长。特别是因为现在的问题与实现有序地图确实没有太大关系,并且真的关于循环中的有用工作。
此外,我有几个不同的键和值类型。因此,每次我想按顺序遍历映射时,我都会复制/粘贴所有代码,并用新值查找/替换MyKey
,并用新值替换MyValue
。复制/粘贴那个大小是......“臭”。它已经成为一个麻烦,因为我已经犯了几个错误,我不得不多次修复。
这种技术也有缺点,它需要对所有键和值进行完整复制。这是不可取的,但我没有看到解决办法。 (我可以将它减少到只是按键,但它不会改变问题的主要性质。)
This question正尝试使用字符串做同样的事情。 This question用字符串和整数进行处理。 This question意味着你需要使用反射,并且必须有一个switch语句来切换每种可能的类型,包括所有用户定义的类型。
但是,对于那些疑惑地图不能确定性地迭代的人来说,似乎有一个更好的解决方案来解决这个问题。我来自OO背景,所以我可能错过了一些基本的东西。
那么,有没有一种合理的方式来迭代地图?
更新:编辑的问题有关于源的详细信息,如果有比这更好的解决方案。
我有很多事情需要分组输出。每个分组层是看起来像这些的结构:
type ObjTypeTree struct {
Children map[Type]*ObjKindTree
TotalCount uint
}
type ObjKindTree struct {
Children map[Kind]*ObjAreaTree
TotalCount uint
}
type ObjAreaTree struct {
Children map[Area]*ObjAreaTree
TotalCount uint
Objs []*Obj
}
然后,我会遍历在ObjTypeTree
孩子打印类型分组。对于其中的每一个,我遍历ObjKindTree
以打印Kind组。迭代是通过类型上的方法完成的,每种类型都需要一些打印分组级别的方法。组需要按顺序打印,这会导致问题。
你已经告诉了我们关于你真正糟糕的解决方案的所有信息。告诉我们你想要解决什么问题,以便我们能够提出好的解决方案。 – peterSO
好的,我已经编辑了一些关于我试图解决的问题的信息。 – alficles