Heim >Backend-Entwicklung >Golang >Wie behalte ich die Einfügereihenfolge beim Durchlaufen einer Go-Map bei?
Durchlaufen einer Karte in Einfügereihenfolge
Karten in Go garantieren keine Iterationsreihenfolge, was frustrierend sein kann, wenn Sie Elemente abrufen möchten in der Reihenfolge, in der sie eingefügt wurden. Es gibt zwar einige Problemumgehungen, diese erfordern jedoch häufig die Verwendung separater Slices oder die Erstellung von Datenduplizierungen, was zu Komplexität und potenziellen Fehlern führen kann.
Lösung mit einem Schlüssel-Slice
Eine praktikable Lösung Die Lösung besteht darin, einen Teil der Schlüssel in der Einfügereihenfolge beizubehalten. Wenn Sie der Karte ein neues Paar hinzufügen, prüfen Sie zunächst, ob der Schlüssel im Slice vorhanden ist. Wenn nicht, hängen Sie den Schlüssel an das Slice an. Verwenden Sie beim Iterieren einfach das Slice, um die Schlüssel der Reihe nach abzurufen und auf die entsprechenden Werte aus der Karte zuzugreifen. Dieser Ansatz hat einen minimalen Overhead, da das Slice nur Schlüssel speichert.
Beispiel:
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]) } }
Lösung mit einer Value Wrapper Linked List
Alternativ können Sie Werte in eine verknüpfte Listenstruktur einbinden. Jeder Wert-Wrapper enthält den tatsächlichen Wert und einen Zeiger auf den nächsten Schlüssel in der Liste. Wenn Sie ein neues Paar hinzufügen, legen Sie den nächsten Zeiger des vorherigen Wert-Wrappers so fest, dass er auf den neuen Schlüssel zeigt. Beginnen Sie beim Iterieren mit dem ersten Schlüssel und befolgen Sie die nächsten Hinweise, um die Werte der Reihe nach abzurufen.
Beispiel:
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 } }
Vergleich
Der Schlüssel-Slice-Ansatz ist einfacher, aber für die Elemententfernung weniger effizient, da er eine lineare Suche im Slice erfordert. Der Value-Wrapper-Linked-List-Ansatz ermöglicht eine schnelle Elemententfernung und eignet sich daher besser für Fälle, in denen häufiges Löschen zu erwarten ist.
Letztendlich hängt die beste Wahl von den spezifischen Anforderungen Ihrer Anwendung ab.
Das obige ist der detaillierte Inhalt vonWie behalte ich die Einfügereihenfolge beim Durchlaufen einer Go-Map bei?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!