Eu só tive um problema em que eu tinha uma variedade de estruturas, por exemplo
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)
}
Vamos dizer que você deseja classificá-lo por Axis
. Como você faz isso?
(Nota: vi http://golang.org/pkg/sort/ e parece funcionar, mas tenho que adicionar cerca de 20 linhas apenas para uma classificação simples por uma chave muito simples. Tenho um fundo python onde está tão simples quanto sorted(planets, key=lambda n: n.Axis)
- existe algo semelhante simples no Go?)
Respostas:
UPDATE: Esta resposta está relacionada a versões anteriores do
go
. Para o Go 1.8 e mais recente, consulte a resposta do AndreKR abaixo .Se você quiser algo um pouco menos detalhado que o
sort
pacote de biblioteca padrão , poderá usar ogithub.com/bradfitz/slice
pacote de terceiros . Ele usa alguns truques para gerar os métodosLen
eSwap
necessários para classificar sua fatia, portanto, você só precisa fornecer umLess
método.Com este pacote, você pode executar a classificação com:
A
planets[:]
peça é necessária para produzir uma fatia cobrindo sua matriz. Se você fizerplanets
uma fatia em vez de uma matriz, poderá pular essa parte.fonte
A partir do Go 1.8, agora você pode usar o sort.Slice para classificar uma fatia:
Normalmente, não há motivo para usar uma matriz em vez de uma fatia, mas, no seu exemplo, você está usando uma matriz, portanto, é necessário sobrepor-la com uma fatia (adicionar
[:]
) para fazê-la funcionarsort.Slice
:A classificação altera a matriz, portanto, se você realmente deseja, pode continuar usando a matriz em vez da fatia após a classificação.
fonte
sort.Slice
é meio que surpreendente. Aless
função usa apenas índices e, portanto, precisa (nesta resposta) usar umaplanets
matriz capturada separadamente . Parece não haver nada que imponha que a fatia classificada e aless
função estejam operando nos mesmos dados. Para que isso funcione, você deve digitarplanets
três vezes (DRY).planets[:]
é crucial. Mas eu não entendo o porquê. Funciona embora.[:]
.A partir do Go 1.8, a resposta da @ AndreKR é a melhor solução.
Você pode implementar um tipo de coleção que implementa a interface de classificação .
Aqui está um exemplo de dois tipos que permitem classificar por Eixo ou Nome:
fonte
Você pode, em vez de implementar o
Sort interface
em que[]Planet
você implementa, em um tipo que contém a coleção e um fechamento que fará a comparação. Você deve fornecer a implementação para o fechamento de comparação para cada propriedade.Este método é melhor do que implementar um tipo de classificação para cada propriedade da estrutura.
Essa resposta é quase extraída dos documentos de classificação, por isso não posso dar muito crédito a ela
Como chamá-lo.
Aqui está uma demonstração
fonte
Aqui está outra maneira de reduzir parte da placa da caldeira. Isenção de responsabilidade, utiliza reflexão e perdas do tipo segurança.
Aqui está uma demonstração
Toda a mágica acontece na
Prop
função. É necessária a propriedade struct para classificar e a ordem em que você deseja classificar (ascendente, descendente) e retorna uma função que realizará as comparações.fonte