2017-01-15 7 views
-3

У меня естьКак стабильный обратный сортировать фрагмент в 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.


Редактировать: После нескольких комментариев я сделал явным, что целочисленное значение является нерабочим примером для упрощения проблемы.

+3

Ваш код не работает: https://play.golang.org/p/A3a5FPZL8Q – Aminadav

+0

@Aminadav конечно, это упрощенный пример использования целых чисел , чтобы представить общую проблему. –

ответ

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

Надеется, что это поможет.

+0

Да, безусловно, это помогает. На самом деле это то же самое решение, что и Elwinar. Это должно быть на работе –

+0

Да ... То же, что и Эльвинар. Я только что добавил реализацию для вашего сценария. – aerokite

2

Внедрите интерфейс sort.Interface по типу среза, чтобы вы могли выбрать порядок сортировки и применить к нему устойчивый вид. Пример: https://play.golang.org/p/TWAtH7asi3

+0

Я смотрел на то, что поведение, которое я ищу, не то же самое, что «обратный и стабильный вид». Я хочу, чтобы порядок равного элемента применялся как в исходном списке, а не как в обратном. –

+0

Ну, если я не ошибаюсь в вашем примере, то код, который я предоставил, работает, и создаст ваш первый пример. – Elwinar

+0

HA! Я вижу, что ты сделал. Вы выполнили Less() как '>'. Это умно. –

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

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