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

时间:2017-01-15 17:43:24

标签: sorting go reverse stability

我确实

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字段反向稳定排序。

编辑:在几条评论之后,我明确指出整数1是一个非工作的例子来简化问题。

3 个答案:

答案 0 :(得分:2)

在切片类型上实现sort.Interface接口,以便您可以选择排序顺序,并对其应用稳定排序。示例:https://play.golang.org/p/TWAtH7asi3

答案 1 :(得分: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)
}

希望这会有所帮助。

答案 2 :(得分:0)

您似乎不需要经历实施排序界面的麻烦。您可以使用sort.Slicesort.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},
    }

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