golang 中没有专门的 map 排序函数,且 map 默认是无序的,也就是你写入的顺序和打印的顺序是不一样的。
m := make(map[string]string, 0)
m["one"] = "one"
m["two"] = "two"
m["three"] = "three"
// 下面两次 for 循环输出的顺序是不一致的
for _, str := range m {fmt.Println(str)}
for _, str := range m {fmt.Println(str)}
如果针对的是简单的 key、value 的形式,可以先把 key 收集到一个 slice 里,然后给 slice 排序,再循环输出对应的 value 即可。
m := make(map[int]string, 0)
m[3] = "three"
m[1] = "one"
m[2] = "two"
var i []int
for key, _ := range m {
i = append(i, key)
}
sort.Ints(i)
for _, v := range i {
fmt.Println(m[v]) // 分别输出 one two three
}
但若要对 golang 的 map 按照 value 进行排序,比如实现网址访问量从高低排序,思路却是不能用 map,而要用 struct 存放 key 和 value,实现 sort 接口,就可以调用 sort。
先封装成个库
package util
type MapSorter []Item
type Item struct {
Key string
Val int64
}
func NewMapSorter(m map[string]int64) MapSorter {
ms := make(MapSorter, 0, len(m))
for k, v := range m {
ms = append(ms, Item{k, v})
}
return ms
}
func (ms MapSorter) Len() int {
return len(ms)
}
func (ms MapSorter) Less(i, j int) bool {
return ms[i].Val > ms[j].Val // 按值排序
//return ms[i].Key < ms[j].Key // 按键排序
}
func (ms MapSorter) Swap(i, j int) {
ms[i], ms[j] = ms[j], ms[i]
}
最后来引用它
m := make(map[string]int64, 0)
m["/v1/tasks"] = 1234
m["/v1/index"] = 100000
m["/v1/comment"] = 18000
m1 := util.NewMapSorter(m)
sort.Sort(m1)
fmt.Println(m1) // [{/v1/index 100000} {/v1/comment 18000} {/v1/tasks 1234}]