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