Si, comme moi, vous trouvez que vous voulez essentiellement le même code de tri à plusieurs endroits, ou que vous voulez simplement réduire la complexité du code, vous pouvez faire abstraction du tri lui-même à une fonction distincte, à laquelle vous passez la fonction qui fait le travail réel que vous souhaitez (qui serait différent à chaque site d'appel, bien sûr).
Étant donné une carte avec le type de clé K
et le type de valeur V
, représentés comme <K>
et <V>
ci - dessous, la fonction de tri commune peut ressembler à ce modèle de code Go (que Go version 1 ne prend pas en charge en l'état):
/* 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)
}
}
Puis appelez-le avec la carte d'entrée et une fonction (en prenant (k <K>, v <V>)
comme arguments d'entrée) qui est appelée sur les éléments de la carte dans l'ordre des touches triées.
Ainsi, une version du code dans la réponse publiée par Mingu pourrait ressembler à:
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()
fonction peut être réutilisée pour tout map[int]string
(en supposant que le même ordre de tri est souhaité), en gardant chaque utilisation à seulement deux lignes de code.
Les inconvénients comprennent:
- C'est plus difficile à lire pour les personnes qui ne sont pas habituées à utiliser des fonctions de première classe
- Cela pourrait être plus lent (je n'ai pas fait de comparaisons de performances)
D'autres langues ont diverses solutions:
- Si l'utilisation de
<K>
et <V>
(pour désigner les types de la clé et de la valeur) semble un peu familière, ce modèle de code n'est pas très différent des modèles C ++.
- Clojure et d'autres langages prennent en charge les cartes triées en tant que types de données fondamentaux.
- Bien que je ne connaisse aucun moyen pour Go de créer
range
un type de première classe tel qu'il puisse être remplacé par une coutume ordered-range
(à la place du range
code d'origine), je pense que certains autres langages fournissent des itérateurs suffisamment puissants pour accomplir la même chose chose.