英文:
Sorting a Map of Structs - GOLANG
问题
我有一个结构体的映射表,通过将数据流传输到Go程序来填充。更新映射表的方式类似于下面的示例。
一旦我填充好这个结构体映射表,最好(或者说好的)的方法是按照结构体中count
字段的值对这个映射表进行排序。
package main
type data struct {
count int64
}
func main() {
m := make(map[string]data)
m["x"] = data{0}
if xx, ok := m["x"]; ok {
xx.count = 2
m["x"] = xx
} else {
panic("X isn't in the map")
}
}
你可以在这里运行这个示例:http://play.golang.org/p/OawL6QIXuO
英文:
I have a map of structs that I am populating by streaming data to a Go program. The way the map is updated is similar to the example below.
Once I have this map of structs populated, what is the best (or good) way to sort this map by the values of the count
field in the struct?
package main
type data struct {
count int64
}
func main() {
m := make(map[string]data)
m["x"] = data{0, 0}
if xx, ok := m["x"]; ok {
xx.count = 2
m["x"] = xx
} else {
panic("X isn't in the map")
}
}
This example can be run here: http://play.golang.org/p/OawL6QIXuO
答案1
得分: 29
正如siritinga已经指出的,map
的元素是无序的,所以你不能对其进行排序。
你可以创建一个slice
,并使用sort
包对元素进行排序:
package main
import (
"fmt"
"sort"
)
type dataSlice []*data
type data struct {
count int64
size int64
}
// Len是sort.Interface的一部分。
func (d dataSlice) Len() int {
return len(d)
}
// Swap是sort.Interface的一部分。
func (d dataSlice) Swap(i, j int) {
d[i], d[j] = d[j], d[i]
}
// Less是sort.Interface的一部分。我们使用count作为排序的值。
func (d dataSlice) Less(i, j int) bool {
return d[i].count < d[j].count
}
func main() {
m := map[string]*data {
"x": {0, 0},
"y": {2, 9},
"z": {1, 7},
}
s := make(dataSlice, 0, len(m))
for _, d := range m {
s = append(s, d)
}
// 我们只是在其中一个结构体上加了3
d := m["x"]
d.count += 3
sort.Sort(s)
for _, d := range s {
fmt.Printf("%+v\n", *d)
}
}
输出:
{count:1 size:7}
{count:2 size:9}
{count:3 size:0}
编辑
更新了示例,使用指针并包含一个map,这样你既可以进行查找,又可以有一个可以排序的slice。
英文:
As siritinga already pointed out, the elements of a map
isn't ordered, so you cannot sort it.
What you can do is to create a slice
and sort the elements using the sort
package:
package main
import (
"fmt"
"sort"
)
type dataSlice []*data
type data struct {
count int64
size int64
}
// Len is part of sort.Interface.
func (d dataSlice) Len() int {
return len(d)
}
// Swap is part of sort.Interface.
func (d dataSlice) Swap(i, j int) {
d[i], d[j] = d[j], d[i]
}
// Less is part of sort.Interface. We use count as the value to sort by
func (d dataSlice) Less(i, j int) bool {
return d[i].count < d[j].count
}
func main() {
m := map[string]*data {
"x": {0, 0},
"y": {2, 9},
"z": {1, 7},
}
s := make(dataSlice, 0, len(m))
for _, d := range m {
s = append(s, d)
}
// We just add 3 to one of our structs
d := m["x"]
d.count += 3
sort.Sort(s)
for _, d := range s {
fmt.Printf("%+v\n", *d)
}
}
Output:
>{count:1 size:7}
{count:2 size:9}
{count:3 size:0}
Edit
Updated the example to use pointers and to include a map so that you can both do lookups and have a slice to sort over.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论