英文:
How do I sort a go slice by multiple values?
问题
我有一个类似上面的结构体切片。如何按照X值首先排序,然后按照Y值排序,就像在SQL中使用ORDER BY X,Y
一样?
我看到你可以使用sort.Slice()
自Go 1.8版本以来,但是否有一种简单的方法可以在不多次循环切片的情况下解决这个问题?
英文:
type Item struct {
Y int
X int
otherProp int
}
I have a slice of structs like the above one. How do I sort the slice item []Item
by the X value first and then by the Y value like in SQLs ORDER BY X,Y
?
I see that you can use sort.Slice()
since go 1.8 but is there a simple way to solve this without looping over the slice several times?
答案1
得分: 2
根据这里的第一个示例:Package sort,我编写了以下代码...
在Less()
函数中,我检查X
是否相等,如果相等,则检查Y
。
package main
import (
"fmt"
"sort"
)
type Item struct {
X int
Y int
otherProp int
}
func (i Item) String() string {
return fmt.Sprintf("X: %d, Y: %d, otherProp: %d\n", i.X, i.Y, i.otherProp)
}
// ByX 根据 X 字段为 []Item 实现 sort.Interface 接口。
type ByX []Item
func (o ByX) Len() int { return len(o) }
func (o ByX) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
func (o ByX) Less(i, j int) bool {
if o[i].X == o[j].X {
return o[i].Y < o[j].Y
} else {
return o[i].X < o[j].X
}
}
func main() {
items := []Item{
{1,2,3},
{5,2,3},
{3,2,3},
{9,2,3},
{1,1,3},
{1,0,3},
}
fmt.Println(items)
sort.Sort(ByX(items))
fmt.Println(items)
}
输出:
[X: 1, Y: 2, otherProp: 3
X: 5, Y: 2, otherProp: 3
X: 3, Y: 2, otherProp: 3
X: 9, Y: 2, otherProp: 3
X: 1, Y: 1, otherProp: 3
X: 1, Y: 0, otherProp: 3
]
[X: 1, Y: 0, otherProp: 3
X: 1, Y: 1, otherProp: 3
X: 1, Y: 2, otherProp: 3
X: 3, Y: 2, otherProp: 3
X: 5, Y: 2, otherProp: 3
X: 9, Y: 2, otherProp: 3
]
英文:
Following the first example from here: Package sort, I wrote the following...
Inside the Less()
function I check if X
are equal and if so, I then check Y
.
package main
import (
"fmt"
"sort"
)
type Item struct {
X int
Y int
otherProp int
}
func (i Item) String() string {
return fmt.Sprintf("X: %d, Y: %d, otherProp: %d\n", i.X, i.Y, i.otherProp)
}
// ByX implements sort.Interface for []Item based on
// the X field.
type ByX []Item
func (o ByX) Len() int { return len(o) }
func (o ByX) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
func (o ByX) Less(i, j int) bool {
if o[i].X == o[j].X {
return o[i].Y < o[j].Y
} else {
return o[i].X < o[j].X
}
}
func main() {
items := []Item{
{1,2,3},
{5,2,3},
{3,2,3},
{9,2,3},
{1,1,3},
{1,0,3},
}
fmt.Println(items)
sort.Sort(ByX(items))
fmt.Println(items)
}
output:
[X: 1, Y: 2, otherProp: 3
X: 5, Y: 2, otherProp: 3
X: 3, Y: 2, otherProp: 3
X: 9, Y: 2, otherProp: 3
X: 1, Y: 1, otherProp: 3
X: 1, Y: 0, otherProp: 3
]
[X: 1, Y: 0, otherProp: 3
X: 1, Y: 1, otherProp: 3
X: 1, Y: 2, otherProp: 3
X: 3, Y: 2, otherProp: 3
X: 5, Y: 2, otherProp: 3
X: 9, Y: 2, otherProp: 3
]
答案2
得分: 1
有没有一种简单的方法可以在不多次循环切片的情况下解决这个问题?
没有。基于比较的排序基本上总是需要至少一次循环切片加上一些额外的操作。但不用担心:sort.Slice并不会做太多的工作。
你有什么问题吗?
英文:
> [...] is there a simple way to solve this without looping over the slice several times?
No. Comparison-based sorting basically always involves looping over the slice at least once plus a bit more. But do not worry: sort.Slice does not do too much work.
What's your question?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论