J'ai juste eu un problème où j'avais un tableau de structures, par exemple
package main
import "log"
type Planet struct {
Name string `json:"name"`
Aphelion float64 `json:"aphelion"` // in million km
Perihelion float64 `json:"perihelion"` // in million km
Axis int64 `json:"Axis"` // in km
Radius float64 `json:"radius"`
}
func main() {
var mars = new(Planet)
mars.Name = "Mars"
mars.Aphelion = 249.2
mars.Perihelion = 206.7
mars.Axis = 227939100
mars.Radius = 3389.5
var earth = new(Planet)
earth.Name = "Earth"
earth.Aphelion = 151.930
earth.Perihelion = 147.095
earth.Axis = 149598261
earth.Radius = 6371.0
var venus = new(Planet)
venus.Name = "Venus"
venus.Aphelion = 108.939
venus.Perihelion = 107.477
venus.Axis = 108208000
venus.Radius = 6051.8
planets := [...]Planet{*mars, *venus, *earth}
log.Println(planets)
}
Disons que vous souhaitez le trier Axis
. Comment tu fais ça?
(Remarque: j'ai vu http://golang.org/pkg/sort/ et cela semble fonctionner, mais je dois ajouter environ 20 lignes juste pour un tri simple par une clé très simple. J'ai un arrière-plan python là où il est aussi simple que sorted(planets, key=lambda n: n.Axis)
- y a-t-il quelque chose de similaire simple dans Go?)
Réponses:
MISE À JOUR: Cette réponse concerne les anciennes versions de
go
. Pour Go 1.8 et plus récent, consultez la réponse d'AndreKR ci-dessous .Si vous voulez quelque chose d'un peu moins verbeux que le
sort
package de bibliothèque standard , vous pouvez utiliser legithub.com/bradfitz/slice
package tiers . Il utilise quelques astuces pour générer les méthodesLen
etSwap
nécessaires pour trier votre tranche, il vous suffit donc de fournir uneLess
méthode.Avec ce package, vous pouvez effectuer le tri avec:
La
planets[:]
pièce est nécessaire pour produire une tranche couvrant votre tableau. Si vous créezplanets
une tranche au lieu d'un tableau, vous pouvez ignorer cette partie.la source
Depuis Go 1.8, vous pouvez désormais utiliser sort.Slice pour trier une tranche:
Il n'y a normalement aucune raison d'utiliser un tableau au lieu d'une tranche, mais dans votre exemple , vous sont en utilisant un tableau, vous devez superposer avec une tranche (ajouter
[:]
) pour le faire fonctionner avecsort.Slice
:Le tri modifie le tableau, donc si vous le souhaitez vraiment, vous pouvez continuer à utiliser le tableau au lieu de la tranche après le tri.
la source
sort.Slice
est assez surprenant. Laless
fonction ne prend que des indices et doit donc (dans cette réponse) utiliser unplanets
tableau capturé séparément . Il semble que rien n'impose que la tranche triée et laless
fonction fonctionnent sur les mêmes données. Pour que cela fonctionne, vous devez taperplanets
trois fois (DRY).planets[:]
est crucial. Mais je ne comprends pas pourquoi. Fonctionne cependant.[:]
.Depuis Go 1.8, la réponse de @ AndreKR est la meilleure solution.
Vous pouvez implémenter un type de collection qui implémente l' interface de tri .
Voici un exemple de deux types de ce type qui vous permettent de trier par axe ou par nom:
la source
Vous pouvez, au lieu d'implémenter le
Sort interface
on,[]Planet
vous implémentez sur un type qui contient la collection et une fermeture qui fera la comparaison. Vous devez fournir l'implémentation de la clôture de comparaison pour chaque propriété.Cette méthode est à mon avis meilleure que l'implémentation d'un type Sort pour chaque propriété de la structure.
Cette réponse est presque extraite directement des documents de tri, donc je ne peux pas m'en attribuer beaucoup de mérite
Comment l'appeler.
Voici une démo
la source
Voici une autre façon de réduire une partie de la plaque de la chaudière. Clause de non-responsabilité, il utilise la sécurité de type réflexion et pertes.
Voici une démo
Toute la magie se produit dans la
Prop
fonction. Il prend la propriété struct pour trier et l'ordre dans lequel vous voulez trier (croissant, décroissant) et retourne une fonction qui effectuera les comparaisons.la source