golang 中 map 排序

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}]

你可能感兴趣的:(Go,golang,开发语言,后端)