Se, como eu, você descobrir que deseja essencialmente o mesmo código de classificação em mais de um lugar, ou apenas deseja manter a complexidade do código baixa, pode abstrair a própria classificação para uma função separada, para a qual você passa a função que faz o trabalho real que você deseja (que seria diferente em cada local de chamada, é claro).
Dado um mapa com tipo de chave K
e tipo de valor V
, representado como <K>
e <V>
abaixo, a função de classificação comum pode ser semelhante a este modelo Go-code (que Go versão 1 não suporta no estado em que se encontra):
/* Go apparently doesn't support/allow 'interface{}' as the value (or
/* key) of a map such that any arbitrary type can be substituted at
/* run time, so several of these nearly-identical functions might be
/* needed for different key/value type combinations. */
func sortedMap<K><T>(m map[<K>]<V>, f func(k <K>, v <V>)) {
var keys []<K>
for k, _ := range m {
keys = append(keys, k)
}
sort.Strings(keys) # or sort.Ints(keys), sort.Sort(...), etc., per <K>
for _, k := range keys {
v := m[k]
f(k, v)
}
}
Em seguida, chame-o com o mapa de entrada e uma função (tomando (k <K>, v <V>)
como seus argumentos de entrada) que é chamada sobre os elementos do mapa na ordem de chave classificada.
Portanto, uma versão do código na resposta postada por Mingu pode ser semelhante a:
package main
import (
"fmt"
"sort"
)
func sortedMapIntString(m map[int]string, f func(k int, v string)) {
var keys []int
for k, _ := range m {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
f(k, m[k])
}
}
func main() {
// Create a map for processing
m := make(map[int]string)
m[1] = "a"
m[2] = "c"
m[0] = "b"
sortedMapIntString(m,
func(k int, v string) { fmt.Println("Key:", k, "Value:", v) })
}
A sortedMapIntString()
função pode ser reutilizada para qualquer map[int]string
(assumindo que a mesma ordem de classificação seja desejada), mantendo cada uso em apenas duas linhas de código.
As desvantagens incluem:
- É mais difícil de ler para quem não está acostumado a usar funções de primeira classe
- Pode ser mais lento (não fiz comparações de desempenho)
Outros idiomas têm várias soluções:
- Se o uso de
<K>
e <V>
(para denotar os tipos de chave e valor) parece um pouco familiar, esse modelo de código não é muito diferente dos modelos C ++.
- Clojure e outras linguagens oferecem suporte a mapas classificados como tipos de dados fundamentais.
- Embora eu não saiba de nenhuma maneira de Go fazer
range
um tipo de primeira classe que possa ser substituído por um personalizado ordered-range
(no lugar de range
no código original), acho que algumas outras linguagens fornecem iteradores que são poderosos o suficiente para realizar o mesmo coisa.