英文:
How to stable reverse sort a slice in Go?
问题
我确实有一个列表:
4, 5', 6, 5''
我想要将其进行稳定的逆排序,得到:
6, 5', 5'', 4
而不是:
6, 5'', 5', 4
以下是一个(无效的)代码示例,它无法实现这个目标:
keys := []int{4, 5', 6, 5''}
sort.Stable(sort.Reverse(sort.Ints(keys)))
它会产生以下结果:
6, 5'', 5', 4
这里简化为一个整数切片的问题,但实际上我需要将其应用于一个结构体切片:
type myStruct struct {
t time.Time
d time.Duration
}
并且基于"t"字段进行稳定的逆排序。
编辑:在一些评论后,我明确说明整数示例是一个不起作用的示例,目的是简化问题。
英文:
I do have
4, 5', 6, 5''
and want to reverse stable sort as
6, 5', 5'', 4
but not
6, 5'', 5', 4
This (invalid) code would not work
keys := []int{4, 5', 6, 5''}
sort.Stable(sort.Reverse(sort.Ints(keys)))
it would produce:
6, 5'', 5', 4
Here the problem is shown as simplified as a slice of integers, but In reality I need to use it applied to a slice of structs
type myStruct struct {
t time.Time
d time.Duration
}
and reverse stable sort based in the t
field.
Edit: After few comments I made explicit that the integer one is a non working example to simplify the problem.
答案1
得分: 2
在一个切片类型上实现sort.Interface
接口,这样你就可以选择排序顺序,并对其应用稳定排序。示例:https://play.golang.org/p/TWAtH7asi3
英文:
Implement the sort.Interface
interface on a slice type, so you can choose the sort order, and apply a stable sort on it. Example : https://play.golang.org/p/TWAtH7asi3
答案2
得分: 1
在你的自定义结构上实现sort.Interface
接口。
type myStruct struct{
t time.Time
d time.Duration
}
type Slice []myStruct
func (s Slice) Len() int { return len(s) }
func (s Slice) Less(i, j int) bool {
return (s[i].t).After(s[j].t)
}
func (s Slice) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
在你的情况下,以下函数将根据t
字段以逆序排序:
func (s Slice) Less(i, j int) bool {
return (s[i].t).After(s[j].t)
}
(s[i].t).After(s[j].t)
判断s[i].t
是否在s[j].t
之后。
如果你只想进行排序,可以使用以下函数:
func (s Slice) Less(i, j int) bool {
return (s[i].t).Before(s[j].t)
}
希望这能帮到你。
英文:
Implement the sort.Interface
interface on your custom struct.
type myStruct struct{
t time.Time
d time.Duration
}
type Slice []myStruct
func (s Slice) Len() int { return len(s) }
func (s Slice) Less(i, j int) bool {
return (s[i].t).After(s[j].t)
}
func (s Slice) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
In your case, following function will sort in reverse order based on t
func (s Slice) Less(i, j int) bool {
return (s[i].t).After(s[j].t)
}
(s[i].t).After(s[j].t)
reports whether s[i].t
is after s[j].t
.
If you want only sort, use following one
func (s Slice) Less(i, j int) bool {
return (s[i].t).Before(s[j].t)
}
Hope this will help.
答案3
得分: 0
似乎你不需要费心实现排序接口。你可以直接使用sort.Slice或sort.SliceStable进行排序。
以下是我测试通过的代码(go playground):
package main
import (
"fmt"
"sort"
"time"
)
func main() {
layout := "Jan 2 15:04:05 -0700 MST 2006"
t1, _ := time.Parse(layout, "Jan 2 15:04:05 -0700 MST 2008")
t2, _ := time.Parse(layout, "Jan 2 15:04:05 -0700 MST 2001")
t3, _ := time.Parse(layout, "Jan 2 15:04:05 -0700 MST 2003")
t4, _ := time.Parse(layout, "Jan 2 15:04:05 -0700 MST 2006")
timestamps := []struct {
T time.Time
d time.Duration
}{
{t1, 1},
{t2, 1},
{t3, 1},
{t4, 1},
}
// 正序排序
sort.Slice(timestamps, func(i, j int) bool {
return timestamps[i].T.Before(timestamps[j].T)
})
fmt.Println("按时间排序:", timestamps)
// 逆序排序
sort.Slice(timestamps, func(i, j int) bool {
return timestamps[i].T.After(timestamps[j].T)
})
fmt.Println("按时间逆序排序:", timestamps)
}
英文:
It seems you don't need to go through the trouble of implementing the sort interface. You can just sort bare using sort.Slice or sort.SliceStable.
Here is what worked for me (go playground):
package main
import (
"fmt"
"sort"
"time"
)
func main() {
layout := "Jan 2 15:04:05 -0700 MST 2006"
t1, _ := time.Parse(layout, "Jan 2 15:04:05 -0700 MST 2008")
t2, _ := time.Parse(layout, "Jan 2 15:04:05 -0700 MST 2001")
t3, _ := time.Parse(layout, "Jan 2 15:04:05 -0700 MST 2003")
t4, _ := time.Parse(layout, "Jan 2 15:04:05 -0700 MST 2006")
timestamps := []struct {
T time.Time
d time.Duration
}{
{t1, 1},
{t2, 1},
{t3, 1},
{t4, 1},
}
// forward
sort.Slice(timestamps, func(i, j int) bool {
return timestamps[i].T.Before(timestamps[j].T)
})
fmt.Println("By time:", timestamps)
// reverse
sort.Slice(timestamps, func(i, j int) bool {
return timestamps[i].T.After(timestamps[j].T)
})
fmt.Println("By time:", timestamps)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论