J'ai besoin de trier une tranche d'un type provenant d'un package tiers. En fonction de certaines conditions, l'ordre doit être croissant ou décroissant.
La solution que je trouve est:
type fooAscending []foo
func (v fooAscending) Len() int { return len(v) }
func (v fooAscending) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
func (v fooAscending) Less(i, j int) bool { return v[i].Amount < v[j].Amount }
type fooDescending []foo
func (v fooDescending) Len() int { return len(v) }
func (v fooDescending) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
func (v fooDescending) Less(i, j int) bool { return v[i].Amount > v[j].Amount }
if someCondition {
sort.Sort(fooAscending(array))
} else {
sort.Sort(fooDescending(array))
}
Y a-t-il une meilleure manière de faire cela. 13 lignes de code pour cette tâche et la plupart d'entre elles sont dupliquées, semble un peu trop.
Depuis Go 1.8, il existe un moyen plus simple de trier une tranche qui ne nécessite pas de définir de nouveaux types. Vous créez simplement un lambda Less (anonyme).
a := []int{5, 3, 4, 7, 8, 9}
sort.Slice(a, func(i, j int) bool {
return a[i] < a[j]
})
for _, v := range a {
fmt.Println(v)
}
Cela triera par ordre croissant, si vous voulez le contraire, écrivez simplement a[i] > a[j]
dans la lambda.
Vous cherchez sort.Reverse
. Cela vous permettra de dire:
sort.Sort(sort.Reverse(fooAscending(s)))
Ma réponse ci-dessous est basée sur l'hypothèse que la tranche que vous recevez d'un package tiers est de type Go de base.
Pour trier des tranches de types de base, utilisez les utilitaires de package de tri. Voici un exemple qui trie une tranche de chaîne et une tranche d'int.
package main
import (
"fmt"
"sort"
)
func main() {
sl := []string{"mumbai", "london", "tokyo", "seattle"}
sort.Sort(sort.StringSlice(sl))
fmt.Println(sl)
intSlice := []int{3,5,6,4,2,293,-34}
sort.Sort(sort.IntSlice(intSlice))
fmt.Println(intSlice)
}
La sortie de ce qui précède est:
[london mumbai seattle tokyo]
[-34 2 3 4 5 6 293]
Allez à Go Playground here pour l'essayer vous-même.
Quelques points importants:
Le tri des types Go de base ne nécessite pas d'implémentation de fonctions telles que Len () appartenant à sort.Interface. Vous devez emprunter cette route uniquement pour les types composites.
Enveloppez simplement le type d'un type de base à l'aide d'un fournisseur de méthode d'interface approprié, par ex. StringSlice , IntSlice , ou Float64Slice , et triez.
La tranche est triée sur place et ne renvoie donc pas de copie de la tranche triée.