web-dev-qa-db-fra.com

tranche de tri golang ascendant ou descendant

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.

11
gsf

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.

32
Franck Jeannin

Vous cherchez sort.Reverse . Cela vous permettra de dire:

sort.Sort(sort.Reverse(fooAscending(s)))
10
cnicutar

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:

  1. 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.

  2. 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.

  3. La tranche est triée sur place et ne renvoie donc pas de copie de la tranche triée.

5
user1820956