Đưa ra khối mã này
map[string]int {"hello":10, "foo":20, "bar":20}
Tôi muốn in ra
foo, 20
bar, 20
hello, 10
Theo thứ tự từ cao nhất đến thấp nhất
Cảm ơn!
Câu trả lời:
Tìm thấy câu trả lời trên Golang-nut bởi Andrew Gerrand
Bạn có thể cài đặt giao diện sắp xếp bằng cách viết hàm 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] }
Đối với bài đăng gốc, vui lòng tìm ở đây https://groups.google.com/forum/#!topic/golang-nuts/FT7cjmcL7gw
sort.Reverse
. +1.
Có một hàm sort.Slice mới trong go 1.8, vì vậy bây giờ việc này đơn giản hơn.
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)
}
}
Ví dụ:
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)
}
}
}
Đầu ra:
foo, 20
bar, 20
hello, 10
Tôi thường cần sắp xếp một map[string]int
số thứ mà tôi đang đếm và đã sử dụng như sau.
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
}
Sử dụng nó để lặp lại các phím theo thứ tự giá trị
values := map[string]int{"foo": 10, "bar": 20, "baz": 1}
for i, index := range rankMapStringInt(values) {
fmt.Printf("%3d: %s -> %d", i, index, values[index])
}
Trong trường hợp của tôi, tôi đang xử lý một chương trình mà tôi đã tạo. Trong chương trình này, tôi đã tạo một Bản đồ giống như bạn, với string
và int
. Sau đó, tôi phát hiện ra như bạn rằng Go không thực sự có một cách tích hợp để sắp xếp một cái gì đó như thế này. Tôi đã đọc các câu trả lời khác và không thực sự thích những gì tôi đọc.
Vì vậy, tôi đã cố gắng nghĩ về vấn đề theo cách khác. Go có thể sử dụng sort.Ints
với một lát cắt. Ngoài ra, Go có thể sử dụng sort.Slice với một bộ so sánh tùy chỉnh. Vì vậy, thay vì tạo Bản đồ của string
và int
, tôi đã tạo struct
của
string
và int
. Sau đó, bạn có thể sắp xếp:
package main
import (
"fmt"
"sort"
)
type File struct {
Name string
Size int
}
func main() {
a := []File{{"april.txt", 9}, {"may.txt", 7}}
f := func (n, n1 int) bool {
return a[n].Size < a[n1].Size
}
sort.Slice(a, f)
fmt.Println(a)
}
Điều này sẽ không hiệu quả với tất cả mọi người, vì có thể bạn sẽ buộc phải xử lý bản đồ do người khác tạo ra. Nhưng nó rất hữu ích cho tôi. Phần tốt là, không giống như tất cả các câu trả lời khác, câu trả lời này không sử dụng vòng lặp.
Trước tiên hãy sắp xếp các khóa theo giá trị và sau đó lặp lại bản đồ:
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])
}
}
Less
trả về kết quả sai. Để sắp xếp ngược lại, hãy sử dụng>
.