GolangNote

Golang笔记

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

Permalink

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

Go: go map 排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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]
}

输出:

Bash: 排序结果
1
2
{[One Two Three Ten Fifty] [100 2 3 10 50]}
{[Two Three Ten Fifty One] [2 3 10 50 100]}

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

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

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

Go: 排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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 功能使排序更简单:

Go: slice sort
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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 _, v := range ss {
        fmt.Printf("%s, %d\n", v.Key, v.Value)
    }
}

输出:

Bash: 排序结果
1
2
3
yo, 20
blah, 20
something, 10

本文网址: https://golangnote.com/topic/75.html 转摘请注明来源

Related articles

Golang http client 处理重定向网页

假设一个网址有多个重定向,A-B-C-D,使用 http.Client.Get 最后取得的内容是网址D的内容,我们该手动处理包含重定向的网址。...

Write a Comment to "golang map 按value 大小排序,降序和升序"

Submit Comment Login
Based on Golang + fastHTTP + sdb | go1.20 Processed in 0ms