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

Golang Sort 为 map 添加额外的值

Golang Sort 为 map 添加额外的值

Go
ITMISS 2021-11-22 15:41:25
type GeoNameTally struct {    Id    uint32    Count uint32}type Tally map[uint32]GeoNameTally以上是我拥有的结构。这个想法很简单。我只是在计算某事发生了多少次。func (t Tally) Len() int           { return len(t) }func (t Tally) Less(i, j int) bool { return t[uint32(i)].Count < t[uint32(j)].Count }func (t Tally) Swap(i, j int)      { t[uint32(i)], t[uint32(j)] = t[uint32(j)], t[uint32(i)] }一切正常,直到我开始排序。在排序之前,地图看起来不错:map[1043487:{Id:1043487 Count:1} 1043503:{Id:1043503 Count:1} 1043444:{Id:1043444 Count:1} 1043491:{Id:1043491 Count:1} 1043459:{Id:1043459 Count:1} 1043475:{Id:1043475 Count:1} 1043464:{Id:1043464 Count:1} 1043441:{Id:1043441 Count:1} 1043470:{Id:1043470 Count:1} 1043460:{Id:1043460 Count:1}]但是,sort.Sort(myTally)在地图具有额外值和空值之后,您可以从以下输出中看到:map[1043503:{Id:1043503 Count:1} 1043491:{Id:1043491 Count:1} 1043459:{Id:1043459 Count:1} 1043475:{Id:1043475 Count:1} 4:{Id:0 Count:0} 8:{Id:0 Count:0} 1043487:{Id:1043487 Count:1} 1:{Id:0 Count:0} 5:{Id:0 Count:0} 9:{Id:0 Count:0} 1043470:{Id:1043470 Count:1} 2:{Id:0 Count:0} 6:{Id:0 Count:0} 1043444:{Id:1043444 Count:1} 1043441:{Id:1043441 Count:1} 1043460:{Id:1043460 Count:1} 3:{Id:0 Count:0} 7:{Id:0 Count:0} 1043464:{Id:1043464 Count:1}]我对这三个功能做错了吗?
查看完整描述

2 回答

?
波斯汪

TA贡献1811条经验 获得超4个赞

您将不存在的索引传递给Swap(i, j).


地图类型是复合的。它是根据另外两种类型定义的:键类型和值类型。例子:


map[string]bool

在前面的例子中,string是键类型,bool是值类型。


您可能知道,地图访问返回 1 或 2 个值。在像您这样的 1 返回值上下文中,当给定不存在的索引时,地图访问将返回地图值类型的零值。


这意味着如果您访问m["im_not_defined"]某个mtype 的地图map[string]bool,您将获得一个返回值,该值是bool(地图的值类型)的零值。


您可以通过执行(在 Swap 中)来检查索引是否定义:


if a, k := t[uint32(i)]; k {

    t[uint32(j)] = a

} else {

    panic("undefined index")

}

类似地对于j.


所以基本上,如果i未定义,则将 的零值GeoNameTally分配给t[j]并导致您的“空”(零)值。


无论如何,如果你想对任何东西进行排序,你就必须使用切片。根据定义,地图是无序的。


查看完整回答
反对 回复 2021-11-22
?
慕后森

TA贡献1802条经验 获得超5个赞

从 Go 1.8 开始,有一种更简单的方法可以对切片进行排序,而无需您定义新类型。您只需创建一个 Less(匿名)lambda。


a := []int{5, 3, 4, 7, 8, 9}

sort.Slice(a, func(i, j int) bool {

    return a[i] < a[j]

})

for _, v := range a {

    fmt.Println(v)

}


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

添加回答

举报

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