如何在Go中稳定反向排序切片?

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