У меня просто была проблема, когда у меня был массив структур, например
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)
}
Допустим, вы хотите отсортировать его по Axis
. Как ты это делаешь?
(Примечание: я видел http://golang.org/pkg/sort/, и, похоже, он работает, но мне нужно добавить около 20 строк только для простой сортировки с помощью очень простого ключа. У меня есть фон Python, где он просто как sorted(planets, key=lambda n: n.Axis)
- есть ли что-то подобное в Go?)
Ответы:
ОБНОВЛЕНИЕ: этот ответ относится к более старым версиям
go
. Для Go 1.8 и новее см . Ответ AndreKR ниже .Если вам нужно что-то менее подробное, чем стандартный
sort
пакет библиотеки , вы можете использовать стороннийgithub.com/bradfitz/slice
пакет. Она использует некоторые приемы для созданияLen
иSwap
метод , необходимых для сортировки своего куска, так что вам нужно только предоставитьLess
метод.С помощью этого пакета вы можете выполнить сортировку с помощью:
planets[:]
Часть необходимо произвести срез , охватывающий ваш массив. Если вы сделаетеplanets
срез вместо массива, вы можете пропустить эту часть.источник
Начиная с Go 1.8 теперь вы можете использовать sort.Slice для сортировки фрагментов:
Там обычно нет оснований использовать массив вместо кусочка, но в вашем примере вы которые с помощью массива, так что вы должны наложить его с кусочком (добавить
[:]
) , чтобы заставить его работать сsort.Slice
:Сортировка изменяет массив, поэтому, если вы действительно хотите, вы можете продолжать использовать массив вместо среза после сортировки.
источник
sort.Slice
это немного удивительно.less
Функция принимает только индексы поэтому он должен (в этом ответе) использовать отдельно захваченныйplanets
массив. Кажется, нет ничего, что заставляет отсортированный фрагмент иless
функция работают с одними и теми же данными. Чтобы это сработало, вам нужно набратьplanets
три раза (СУХОЙ).planets[:]
является решающим. Но я не понимаю почему. Хотя работает.[:]
.Что касается Go 1.8, ответ @AndreKR - лучшее решение.
Вы можете реализовать тип коллекции, который реализует интерфейс сортировки .
Вот пример двух таких типов, которые позволяют сортировать по оси или имени:
источник
Вместо реализации
Sort interface
on[]Planet
вы можете реализовать тип, содержащий коллекцию, и замыкание, которое будет выполнять сравнение. Вы должны предоставить реализацию для закрытия сравнения для каждого свойства.Я считаю, что этот метод лучше, чем реализация типа сортировки для каждого свойства структуры.
Этот ответ почти вырван прямо из документации по сортировке, поэтому я не могу поверить в это
Как это назвать.
Вот демо
источник
Вот еще один способ уменьшить часть котельной плиты. Заявление об отказе от ответственности, он использует безопасность типа отражения и потерь.
Вот демо
Вся магия происходит в
Prop
функции. Он принимает свойство структуры для сортировки и порядок, который вы хотите отсортировать (по возрастанию, по убыванию), и возвращает функцию, которая будет выполнять сравнения.источник