如何用它的值对Map [string] int进行排序?

时间:2013-09-09 09:34:29

标签: go

鉴于此代码块

map[string]int {"hello":10, "foo":20, "bar":20}

我想打印出来

foo, 20
bar, 20
hello, 10

按从高到低的顺序

谢谢!

7 个答案:

答案 0 :(得分:74)

Andrew Gerrand找到关于Golang-nuts的答案

您可以通过编写len / less / swap函数

来实现排序接口
func rankByWordCount(wordFrequencies map[string]int) PairList{
  pl := make(PairList, len(wordFrequencies))
  i := 0
  for k, v := range wordFrequencies {
    pl[i] = Pair{k, v}
    i++
  }
  sort.Sort(sort.Reverse(pl))
  return pl
}

type Pair struct {
  Key string
  Value int
}

type PairList []Pair

func (p PairList) Len() int { return len(p) }
func (p PairList) Less(i, j int) bool { return p[i].Value < p[j].Value }
func (p PairList) Swap(i, j int){ p[i], p[j] = p[j], p[i] }

原帖请在https://groups.google.com/forum/#!topic/golang-nuts/FT7cjmcL7gw

找到

答案 1 :(得分:43)

在1.8中有一个新的sort.Slice函数,所以现在这个更简单了。

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

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

https://play.golang.org/p/y1_WBENH4N

答案 2 :(得分:15)

例如:

package main

import (
        "fmt"
        "sort"
)

func main() {
        m := map[string]int{"hello": 10, "foo": 20, "bar": 20}
        n := map[int][]string{}
        var a []int
        for k, v := range m {
                n[v] = append(n[v], k)
        }
        for k := range n {
                a = append(a, k)
        }
        sort.Sort(sort.Reverse(sort.IntSlice(a)))
        for _, k := range a {
                for _, s := range n[k] {
                        fmt.Printf("%s, %d\n", s, k)
                }
        }
}

Playground


输出:

foo, 20
bar, 20
hello, 10

答案 3 :(得分:1)

我经常需要对DetailsAttachments进行计数,并且一直使用以下内容。

map[string]int

使用它按值顺序遍历键

func rankMapStringInt(values map[string]int) []string {
    type kv struct {
        Key   string
        Value int
    }
    var ss []kv
    for k, v := range values {
        ss = append(ss, kv{k, v})
    }
    sort.Slice(ss, func(i, j int) bool {
        return ss[i].Value > ss[j].Value
    })
    ranked := make([]string, len(values))
    for i, kv := range ss {
        ranked[i] = kv.Key
    }
    return ranked
}

答案 4 :(得分:0)

先按值对键进行排序,然后迭代映射:

package main

import (
    "fmt"
    "sort"
)

func main() {
    counts := map[string]int{"hello": 10, "foo": 20, "bar": 20}

    keys := make([]string, 0, len(counts))
    for key := range counts {
        keys = append(keys, key)
    }
    sort.Slice(keys, func(i, j int) bool { return counts[keys[i]] > counts[keys[j]] })

    for _, key := range keys {
        fmt.Printf("%s, %d\n", key, counts[key])
    }
}

答案 5 :(得分:0)

就我而言,我正在处理自己创建的程序。在这个程序中,我 像<ListView ItemsSource="{Binding DailyWeather, Source={StaticResource vm}}" RowHeight="200"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout> <Label Text="{Binding DayOfYear}"/> <ListView ItemsSource="{Binding HourlyWeather}"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout> <Label Text="{Binding Temperature}"/> <Label Text="{Binding Time}"/> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> string一样创建了一个地图。然后我发现像你一样 Go确实没有内置的方式来对此类内容进行排序。我读了 其他答案,并不太喜欢我读的书。

所以我试图以不同的方式来考虑这个问题。 Go可以使用sort.Ints 用一片。此外,Go可以将sort.Slice与自定义比较器一起使用。所以 我没有创建intstring的Map,而是创建了{ intstruct。然后您可以进行排序:

string

这不适用于所有人,因为也许您将不得不面对 别人创建的地图。但这对我很有用。好部分是,与众不同 其他答案,这个没有循环。

答案 6 :(得分:-2)

找到了一个非常简单的答案:https://yourbasic.org/golang/sort-map-keys-values/

逻辑是:

  1. 将键放在一个切片中
  2. 使用排序
  3. 使用有序键片迭代地图