Lors de l'itération de la carte retournée dans le code, renvoyée par la fonction de rubrique, les touches n'apparaissent pas dans l'ordre.
Comment puis-je faire en sorte que les clés soient dans l'ordre / trier la carte afin que les clés soient dans l'ordre et que les valeurs correspondent?
Voici le code .
Réponses:
Le blog Go: Go maps en action a une excellente explication.
Voici ma version modifiée de l'exemple de code: http://play.golang.org/p/dvqcGPYy3-
Production:
la source
keys := make([]int, len(m))
, puis insérer par indexkeys[i] = k
au lieu deappend
Selon la spécification Go , l'ordre d'itération sur une carte n'est pas défini et peut varier entre les exécutions du programme. En pratique, non seulement il n'est pas défini, mais il est en fait volontairement aléatoire. En effet, cela était autrefois prévisible et que les développeurs de langage Go ne voulaient pas que les gens se fient à un comportement non spécifié, ils l'ont donc délibérément aléatoire de sorte qu'il était impossible de se fier à ce comportement.
Ce que vous aurez à faire, alors, est de tirer les clés dans une tranche, de les trier, puis de les placer sur la tranche comme ceci:
la source
Toutes les réponses ici contiennent maintenant l'ancien comportement des cartes. Dans Go 1.12+, vous pouvez simplement imprimer une valeur de carte et elle sera automatiquement triée par clé. Cela a été ajouté car il permet de tester facilement les valeurs de la carte.
En savoir plus ici .
la source
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 valeurV
, 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):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 à:
La
sortedMapIntString()
fonction peut être réutilisée pour toutmap[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:
D'autres langues ont diverses solutions:
<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 ++.range
un type de première classe tel qu'il puisse être remplacé par une coutumeordered-range
(à la place durange
code d'origine), je pense que certains autres langages fournissent des itérateurs suffisamment puissants pour accomplir la même chose chose.la source
En réponse à James Craig Burley réponse . Afin de créer une conception propre et réutilisable, on peut choisir une approche plus orientée objet. De cette façon, les méthodes peuvent être liées en toute sécurité aux types de la carte spécifiée. Pour moi, cette approche me semble plus propre et organisée.
Exemple:
Exemple de terrain de jeu étendu avec plusieurs types de cartes.
Note importante
Dans tous les cas, la carte et la tranche triée sont découplées à partir du moment où la
for
boucle sur la carterange
est terminée. Cela signifie que si la carte est modifiée après la logique de tri, mais avant de l'utiliser, vous pouvez avoir des problèmes. (Pas de thread / Go routine sûre). S'il y a un changement d'accès en écriture à la carte parallèle, vous devrez utiliser un mutex autour des écritures et de lafor
boucle triée .la source
Cela vous fournit l'exemple de code sur la carte de tri. En gros, voici ce qu'ils fournissent:
et c'est ce que je suggérerais d'utiliser à la place :
Le code complet peut être trouvé dans ce Go Playground .
la source