为了账号安全,请及时绑定邮箱和手机立即绑定

有没有一种简单的方法可以按顺序迭代地图?

有没有一种简单的方法可以按顺序迭代地图?

Go
jeck猫 2021-06-16 22:08:56
这是古老的“为什么我的地图打印乱序”问题的变体。我有一个(相当多)形式的映射map[MyKey]MyValue, whereMyKey和MyValueare(通常)结构。对于所有键类型,我都有“较少”的功能。我需要按顺序遍历地图。(具体来说,该类型上的 less 函数定义的顺序。)现在,我的代码如下所示:type PairKeyValue struct {    MyKey    MyValue}type PairKeyValueSlice []Pairfunc (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]MyValuem = GetMapFromSomewhereUseful()for _, kv := range NewPairKeyValueSlice(m) {    key := kv.MyKey    value := kv.MyValue    DoUsefulWork(key, value)}这似乎在很大程度上有效。问题是它非常冗长。特别是因为手头的问题实际上与实现有序映射关系不大,而实际上与循环中的有用工作有关。另外,我有几种不同的键和值类型。因此,每次我想按顺序遍历地图时,我都会复制/粘贴所有代码,并MyKey使用新键和MyValue新值进行查找/替换。在那个量级上复制/粘贴是......“臭”。它已经变得很麻烦,因为我已经犯了一些错误,我不得不多次修复。这种技术也有缺点,它需要制作所有键和值的完整副本。这是不可取的,但我认为没有办法解决它。(我可以将其简化为键,但它不会改变问题的主要性质。)这个问题试图用字符串做同样的事情。这个问题用字符串和整数来完成。这个问题意味着您需要使用反射,并且必须有一个 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 分组。迭代是通过类型上的方法完成的,每种类型都需要一些不同的方式来打印其分组级别。组需要按顺序打印,这会导致问题。
查看完整描述

2 回答

?
守着一只汪

TA贡献1872条经验 获得超3个赞

如果需要整理密钥,请不要使用地图。使用 B 树或任何其他/类似的有序容器。


查看完整回答
反对 回复 2021-06-21
  • 2 回答
  • 0 关注
  • 155 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信