Skip to content

πŸ”ƒ An ordered map in Go with amortized O(1) for Set, Get, Delete and Len.

License

Notifications You must be signed in to change notification settings

elliotchance/orderedmap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

9d80274 Β· Jan 2, 2025

History

25 Commits
Dec 4, 2024
Jan 2, 2025
Jan 2, 2025
Nov 18, 2019
Nov 15, 2019
Apr 27, 2020
Dec 4, 2024
Feb 5, 2021
Feb 5, 2021
Sep 7, 2022
Jan 2, 2025
Jan 2, 2025

Repository files navigation

πŸ”ƒ github.com/elliotchance/orderedmap/v3 GoDoc

Basic Usage

An *OrderedMap is a high performance ordered map that maintains amortized O(1) for Set, Get, Delete and Len:

import "github.com/elliotchance/orderedmap/v3"

func main() {
	m := orderedmap.NewOrderedMap[string, any]()

	m.Set("foo", "bar")
	m.Set("qux", 1.23)
	m.Set("123", true)

	m.Delete("qux")
}

Note

  • v3 requires Go v1.23 - If you need to support Go 1.18-1.22, you can use v2.
  • v2 requires Go v1.18 for generics - If you need to support Go 1.17 or below, you can use v1.

Internally an *OrderedMap uses the composite type map combined with a trimmed down linked list to maintain the order.

Iterating

The following methods all return iterators that can be used to loop over elements in an ordered map:

  • AllFromFront()
  • AllFromBack()
  • Keys()
  • Values()
// Iterate through all elements from oldest to newest:
for key, value := range m.AllFromFront() {
	fmt.Println(key, value)
}

Iterators are safe to use bidirectionally, and will return nil once it goes beyond the first or last item. If the map is changing while the iteration is in-flight it may produce unexpected behavior.

If you want to get a slice of the map keys or values, you can use the standard slices.Collect method with the iterator returned from Keys() or Values():

fmt.Println(slices.Collect(m.Keys())
// [A B C]

Likewise, calling maps.Collect on the iterator returned from AllFromFront() will create a regular unordered map from the ordered one:

fmt.Println(maps.Collect(m.AllFromFront())
// [A:1 B:2 C:3]

If you don't want to use iterators, you can also manually loop over the elements using Front() or Back() with Next():

// Iterate through all elements from oldest to newest:
for el := m.Front(); el != nil; el = el.Next() {
    fmt.Println(el.Key, el.Value)
}

// You can also use Back and Prev to iterate in reverse:
for el := m.Back(); el != nil; el = el.Prev() {
    fmt.Println(el.Key, el.Value)
}