Po prostu miałem problem gdzie miałem tablicę struktur np
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)
}
Powiedzmy, że chcesz to posortować Axis
. Jak to robisz?
(Uwaga: widziałem http://golang.org/pkg/sort/ i wygląda na to, że działa, ale muszę dodać około 20 wierszy tylko w celu prostego sortowania za pomocą bardzo prostego klucza. Mam tło w Pythonie, gdzie jest tak proste, jak sorted(planets, key=lambda n: n.Axis)
- czy jest coś podobnego prostego w Go?)
Odpowiedzi:
AKTUALIZACJA: Ta odpowiedź dotyczy starszych wersji
go
. Dla Go 1.8 i nowszych, zobacz odpowiedź AndreKR poniżej .Jeśli chcesz czegoś mniej szczegółowego niż standardowy
sort
pakiet biblioteki , możesz użyćgithub.com/bradfitz/slice
pakietu innej firmy . Wykorzystuje kilka sztuczek do generowania metodLen
iSwap
potrzebnych do sortowania wycinka, więc wystarczy podaćLess
metodę.Za pomocą tego pakietu możesz przeprowadzić sortowanie za pomocą:
planets[:]
Część jest niezbędna do wytworzenia kawałek obejmującą swoją tablicę. Jeśli utworzyszplanets
plasterek zamiast tablicy, możesz pominąć tę część.źródło
Od wersji Go 1.8 możesz teraz sortować plasterki za pomocą sort.Slice :
Zwykle nie ma powodów, by używać tablicy zamiast plasterka, ale w swoim przykładzie ty są za pomocą tablicy, więc trzeba nałożyć go z plasterkiem (dodaj
[:]
) w celu uczynienia go pracy zsort.Slice
:Sortowanie zmienia tablicę, więc jeśli naprawdę chcesz, możesz nadal używać tablicy zamiast wycinka po sortowaniu.
źródło
sort.Slice
jest trochę zaskakujące.less
Funkcja zajmuje tylko indeksy więc musi (w tym odpowiedzi) używać osobno przechwyconyplanets
tablicę. Wydaje się, że nic nie wymusza, aby posortowany wycinek iless
funkcja działały na tych samych danych. Aby to zadziałało, musisz wpisaćplanets
trzy razy (DRY).planets[:]
jest kluczowe. Ale nie rozumiem dlaczego. Ale działa.[:]
.Począwszy od idź 1,8 @ AndreKR za odpowiedź jest lepszym rozwiązaniem.
Możesz zaimplementować typ kolekcji, który implementuje interfejs sortowania .
Oto przykład dwóch takich typów, które umożliwiają sortowanie według osi lub nazwy:
źródło
Możesz zamiast implementować
Sort interface
on,[]Planet
który zaimplementujesz w typie zawierającym kolekcję i zamknięcie, które wykona porównanie. Musisz podać implementację zamknięcia porównania dla każdej właściwości.Uważam, że ta metoda jest lepsza niż implementacja typu Sort dla każdej właściwości struktury.
Ta odpowiedź jest prawie wyrwana z różnych dokumentów, więc nie mogę przypisać jej zbyt wiele uznania
Jak to nazwać.
Oto demo
źródło
Oto inny sposób na zmniejszenie części płyty kotła. Zastrzeżenie, wykorzystuje odbicie i bezpieczeństwo typu strat.
Oto demo
Cała magia dzieje się w
Prop
funkcji. Pobiera właściwość struct do sortowania i kolejność, w jakiej chcesz sortować (rosnąco, malejąco) i zwraca funkcję, która wykona porównania.źródło