Maison > développement back-end > Golang > Comment conserver l'ordre d'insertion lors d'une itération sur une carte Go ?

Comment conserver l'ordre d'insertion lors d'une itération sur une carte Go ?

Patricia Arquette
Libérer: 2024-12-20 00:29:09
original
885 Les gens l'ont consulté

How to Maintain Insertion Order When Iterating Through a Go Map?

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])
    }
}
Copier après la connexion

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
    }
}
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal