Golang笔记

golang map 按value 大小排序,降序和升序

map 按value 大小排序,降序和升序。

package main

import "fmt"
import "sort"

func main() {
    m := map[string]int{
        "One":   100,
        "Two":   2,
        "Three": 3,
        "Ten":   10,
        "Fifty": 50,
    }
    vs := NewValSorter(m)
    fmt.Printf("%v\n", *vs)
    vs.Sort()
    fmt.Printf("%v\n", *vs)
}

type ValSorter struct {
    Keys []string
    Vals []int
}

func NewValSorter(m map[string]int) *ValSorter {
    vs := &ValSorter{
        Keys: make([]string, 0, len(m)),
        Vals: make([]int, 0, len(m)),
    }
    for k, v := range m {
        vs.Keys = append(vs.Keys, k)
        vs.Vals = append(vs.Vals, v)
    }
    return vs
}

func (vs *ValSorter) Sort() {
    sort.Sort(vs)
}

func (vs *ValSorter) Len() int           { return len(vs.Vals) }
func (vs *ValSorter) Less(i, j int) bool { return vs.Vals[i] < vs.Vals[j] }
func (vs *ValSorter) Swap(i, j int) {
    vs.Vals[i], vs.Vals[j] = vs.Vals[j], vs.Vals[i]
    vs.Keys[i], vs.Keys[j] = vs.Keys[j], vs.Keys[i]
}

输出:

{[One Two Three Ten Fifty] [100 2 3 10 50]}
{[Two Three Ten Fifty One] [2 3 10 50 100]}

这是按升序排序,如果要按降序排列则修改下面一行:

func (vs *ValSorter) Less(i, j int) bool { return vs.Vals[i] > vs.Vals[j] }

下面另一种实现简单一些:

package main

// sort a map's keys in descending order of its values.

import "sort"
import "fmt"

type sortedMap struct {
    m map[string]int
    s []string
}

func (sm *sortedMap) Len() int {
    return len(sm.m)
}

func (sm *sortedMap) Less(i, j int) bool {
    return sm.m[sm.s[i]] > sm.m[sm.s[j]]
}

func (sm *sortedMap) Swap(i, j int) {
    sm.s[i], sm.s[j] = sm.s[j], sm.s[i]
}

func sortedKeys(m map[string]int) []string {
    sm := new(sortedMap)
    sm.m = m
    sm.s = make([]string, len(m))
    i := 0
    for key, _ := range m {
        sm.s[i] = key
        i++
    }
    sort.Sort(sm)
    return sm.s
}

func main() {
    s := []string{"Python", "Python", "Python", "igor", "igor", "igor", "igor", "go", "go", "Golang", "Golang", "Golang", "Golang", "Py", "Py"}
    count := make(map[string]int)

    for _, v := range s {
        count[v]++
    }

    for _, res := range sortedKeys(count) {
        fmt.Println(res, count[res])
    }

}

go1.8 后提供的slice sort 功能使排序更简单:

package main

import (
    "fmt"
    "sort"
)

func main() {
    m := map[string]int{
        "something": 10,
        "yo":        20,
        "blah":      20,
    }

    type kv struct {
        Key   string
        Value int
    }

    var ss []kv
    for k, v := range m {
        ss = append(ss, kv{k, v})
    }

    sort.Slice(ss, func(i, j int) bool {
        return ss[i].Value > ss[j].Value  // 降序
        // return ss[i].Value > ss[j].Value  // 升序
    })

    for _, kv := range ss {
        fmt.Printf("%s, %d\n", kv.Key, kv.Value)
    }
}

输出:

yo, 20
blah, 20
something, 10
本文网址: https://golangnote.com/topic/75.html (转载注明出处)
关于GolangNote:记录在工作中使用golang 遇到、面临的相关问题及解决方法。如果你在这里获得一些知识或信息,解决你的编程问题,请考虑捐赠给不幸的人或者你喜欢的慈善机构,除捐赠外,种植树木、志愿服务或减少排碳的行为也很有益处。如果你有任何问题可以在下面 留言
Be the first to comment!
Captcha image
Relative Articles