This is a fork of https://github.com/wk8/go-ordered-map to use generics for performance reasons. As such it requires Go 1.18+.
Same as regular maps, but also remembers the order in which keys were inserted, akin to Python's collections.OrderedDicts.
It offers the following features:
- optimal runtime performance (all operations are constant time)
- optimal memory usage (only one copy of values, no unnecessary memory allocation)
- allows iterating from newest or oldest keys indifferently, without memory copy, allowing to
breakthe iteration, and in time linear to the number of keys iterated over rather than the total length of the ordered map - idiomatic API, akin to that of
container/list
go get -u github.com/DominicTobias/go-ordered-mapThe full documentation is available on godoc.org.
package main
import (
"fmt"
"github.com/DominicTobias/go-ordered-map"
)
func main() {
om := orderedmap.New[string, string]()
om.Set("foo", "bar")
om.Set("bar", "baz")
om.Set("coucou", "toi")
fmt.Println(om.Get("foo")) // => bar, true
fmt.Println(om.Get("i dont exist")) // => <nil>, false
// iterating pairs from oldest to newest:
for pair := om.Oldest(); pair != nil; pair = pair.Next() {
fmt.Printf("%s => %s\n", pair.Key, pair.Value)
} // prints:
// foo => bar
// bar => baz
// coucou => toi
// iterating over the 2 newest pairs:
i := 0
for pair := om.Newest(); pair != nil; pair = pair.Prev() {
fmt.Printf("%s => %s\n", pair.Key, pair.Value)
i++
if i >= 2 {
break
}
} // prints:
// coucou => toi
// bar => baz
}type myStruct struct {
payload string
}
func main() {
om := orderedmap.New[int, string]()
om.Set(12, &myStruct{"foo"})
om.Set(1, &myStruct{"bar"})
value, present := om.Get(12)
if !present {
panic("should be there!")
}
fmt.Println(value.payload) // => foo
for pair := om.Oldest(); pair != nil; pair = pair.Next() {
fmt.Printf("%d => %s\n", pair.Key, pair.Value.payload)
} // prints:
// 12 => foo
// 1 => bar
}There are several other ordered map golang implementations out there, but I believe that at the time of writing none of them offer the same functionality as this library; more specifically:
- iancoleman/orderedmap only accepts
stringkeys, itsDeleteoperations are linear - cevaris/ordered_map uses a channel for iterations, and leaks goroutines if the iteration is interrupted before fully traversing the map
- mantyr/iterator also uses a channel for iterations, and its
Deleteoperations are linear - samdolan/go-ordered-map adds unnecessary locking (users should add their own locking instead if they need it), its
DeleteandGetoperations are linear, iterations trigger a linear memory allocation