Parcourir une carte dans l'ordre d'insertion
Les cartes dans Go ne garantissent pas l'ordre des itérations, ce qui peut être frustrant lorsque vous souhaitez récupérer des éléments dans l'ordre dans lequel ils ont été insérés. Bien que certaines solutions de contournement existent, elles impliquent souvent l'utilisation de tranches distinctes ou la création de duplications de données, ce qui peut entraîner une complexité et des bugs potentiels.
Solution avec une tranche de clé
Une solution viable La solution consiste à conserver une tranche de clés dans l’ordre d’insertion. Lors de l'ajout d'une nouvelle paire à la carte, vérifiez d'abord si la clé existe dans la tranche. Sinon, ajoutez la clé à la tranche. Lors de l'itération, utilisez simplement la tranche pour récupérer les clés dans l'ordre et accéder aux valeurs correspondantes depuis la carte. Cette approche entraîne une surcharge minime puisque la tranche ne stocke que les clés.
Exemple :
type Key int type Value int type OrderedMap struct { m map[Key]Value keys []Key } func NewOrderedMap() *OrderedMap { return &OrderedMap{m: make(map[Key]Value)} } func (om *OrderedMap) Set(k Key, v Value) { if _, ok := om.m[k]; !ok { om.keys = append(om.keys, k) } om.m[k] = v } func (om *OrderedMap) Range() { for _, k := range om.keys { fmt.Println(om.m[k]) } }
Solution avec une liste chaînée Value Wrapper
Vous pouvez également envelopper les valeurs dans une structure de liste chaînée. Chaque wrapper de valeur contient la valeur réelle et un pointeur vers la clé suivante dans la liste. Lors de l’ajout d’une nouvelle paire, définissez le pointeur suivant du wrapper de valeur précédent pour qu’il pointe vers la nouvelle clé. Lors de l'itération, commencez par la première clé et suivez les pointeurs suivants pour récupérer les valeurs dans l'ordre.
Exemple :
type Key int type Value int type ValueWrapper struct { v Value next *Key } type OrderedMap struct { m map[Key]ValueWrapper first, last *Key } func NewOrderedMap() *OrderedMap { return &OrderedMap{m: make(map[Key]ValueWrapper)} } func (om *OrderedMap) Set(k Key, v Value) { if _, ok := om.m[k]; !ok && om.last != nil { pw2 := om.m[*om.last] om.m[*om.last] = ValueWrapper{pw2.v, &k} } pw := ValueWrapper{v: v} om.m[k] = pw if om.first == nil { om.first = &k } om.last = &k } func (om *OrderedMap) Range() { for k := om.first; k != nil; { pw := om.m[*k] fmt.Println(pw.v) k = pw.next } }
Comparaison
L'approche par tranche de clé est plus simple mais moins efficace pour la suppression d'éléments car elle nécessite une recherche linéaire dans la tranche. L'approche de liste chaînée de wrapper de valeurs permet une suppression rapide d'éléments, ce qui la rend plus adaptée aux cas où des suppressions fréquentes sont attendues.
En fin de compte, le meilleur choix dépend des exigences spécifiques de votre application.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!