Se, come me, scopri di volere essenzialmente lo stesso codice di ordinamento in più di un posto, o vuoi semplicemente mantenere bassa la complessità del codice, puoi astrarre l'ordinamento stesso a una funzione separata, a cui passi la funzione che fa il lavoro effettivo che desideri (che sarebbe diverso in ogni sito della chiamata, ovviamente).
Data una mappa con tipo di chiave Ke tipo di valore V, rappresentata come <K>e di <V>seguito, la funzione di ordinamento comune potrebbe assomigliare a questo modello di codice Go (che Go versione 1 non supporta così com'è):
/* 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)
}
}
Quindi chiamalo con la mappa di input e una funzione (prendendo (k <K>, v <V>)come argomenti di input) che viene chiamata sugli elementi della mappa in ordine di tasti ordinati.
Quindi, una versione del codice nella risposta pubblicata da Mingu potrebbe essere simile 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) })
}
La sortedMapIntString()funzione può essere riutilizzata per qualsiasi map[int]string(supponendo che si desideri lo stesso ordinamento), mantenendo ogni utilizzo a sole due righe di codice.
Gli svantaggi includono:
- È più difficile da leggere per le persone non abituate a usare le funzioni come di prima classe
- Potrebbe essere più lento (non ho effettuato confronti delle prestazioni)
Altre lingue hanno varie soluzioni:
- Se l'uso di
<K>e <V>(per indicare i tipi per la chiave e il valore) sembra un po 'familiare, quel modello di codice non è molto diverso dai modelli C ++.
- Clojure e altri linguaggi supportano le mappe ordinate come tipi di dati fondamentali.
- Sebbene non conosca in alcun modo Go rende
rangeun tipo di prima classe tale da poter essere sostituito con un custom ordered-range(al posto del rangecodice originale), penso che alcuni altri linguaggi forniscano iteratori che sono abbastanza potenti da ottenere lo stesso cosa.