Saya baru saja mengalami masalah di mana saya memiliki array struct, misalnya
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)
}
Katakanlah Anda ingin mengurutkannya Axis
. Bagaimana kamu melakukannya?
(Catatan: Saya telah melihat http://golang.org/pkg/sort/ dan tampaknya berhasil, tetapi saya harus menambahkan sekitar 20 baris hanya untuk penyortiran sederhana dengan kunci yang sangat sederhana. Saya memiliki latar belakang python di mana itu sesederhana sorted(planets, key=lambda n: n.Axis)
- apakah ada hal serupa yang sederhana di Go?)
Jawaban:
PEMBARUAN: Jawaban ini berkaitan dengan versi yang lebih lama dari
go
. Untuk Go 1.8 dan yang lebih baru, lihat jawaban AndreKR di bawah .Jika Anda menginginkan sesuatu yang sedikit lebih bertele-tele daripada
sort
paket perpustakaan standar , Anda dapat menggunakangithub.com/bradfitz/slice
paket pihak ketiga . Ini menggunakan beberapa trik untuk menghasilkanLen
danSwap
metode yang diperlukan untuk mengurutkan potongan Anda, jadi Anda hanya perlu menyediakanLess
metode.Dengan paket ini, Anda dapat melakukan pengurutan dengan:
Bagian
planets[:]
tersebut diperlukan untuk menghasilkan irisan yang menutupi array Anda. Jika Anda membuatplanets
irisan alih-alih larik, Anda dapat melewati bagian itu.sumber
Mulai Go 1.8, Anda sekarang dapat menggunakan sort.Slice untuk mengurutkan slice:
Biasanya tidak ada alasan untuk menggunakan array daripada sepotong, tetapi dalam contoh Anda sedang menggunakan sebuah array, sehingga Anda harus menyalutnya dengan sepotong (add
[:]
) untuk membuatnya bekerja dengansort.Slice
:Pengurutan mengubah larik, jadi jika Anda benar-benar ingin, Anda dapat terus menggunakan larik alih-alih potongan setelah pengurutan.
sumber
sort.Slice
agak mengejutkan. Theless
Fungsi hanya membutuhkan indeks sehingga harus (dalam jawaban ini) menggunakan secara terpisah-ditangkapplanets
larik. Tampaknya tidak ada yang memaksa bahwa slice yang diurutkan danless
fungsinya beroperasi pada data yang sama. Agar ini berfungsi, Anda harus mengetikplanets
tiga kali (KERING).planets[:]
sangat penting. Tapi saya tidak mengerti kenapa. Bekerja meskipun.[:]
.Mulai Go 1.8, jawaban @ AndreKR adalah solusi yang lebih baik.
Anda bisa mengimplementasikan tipe koleksi yang mengimplementasikan antarmuka sort .
Berikut adalah contoh dari dua tipe yang memungkinkan Anda untuk mengurutkan berdasarkan Axis atau Name:
sumber
Anda bisa, daripada mengimplementasikan
Sort interface
on yang[]Planet
Anda implementasikan pada tipe yang berisi collection dan closure yang akan melakukan perbandingan. Anda harus menyediakan implementasi untuk penutupan perbandingan untuk setiap properti.Metode ini saya rasa lebih baik daripada menerapkan tipe Sortir untuk setiap properti struct.
Jawaban ini hampir robek langsung dari dokumen sortir jadi saya tidak bisa terlalu menghargai itu
Bagaimana menyebutnya.
Ini Demo
sumber
Berikut cara lain untuk mengurangi sebagian pelat boiler. Penafian, ini menggunakan keamanan tipe refleksi dan kerugian.
Ini Demo
Semua keajaiban terjadi dalam
Prop
fungsinya. Dibutuhkan properti struct untuk mengurutkan dan mengurutkan yang ingin Anda urutkan (naik, turun) dan mengembalikan fungsi yang akan melakukan perbandingan.sumber