omap

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2026 License: MIT Imports: 7 Imported by: 0

README

omap

omap provides an ordered map implementation for Go. Unlike Go's standard map, omap maintains the insertion order of keys. It leverages Go iterators and supports generic key-value types.

Features

  • Ordered: Maintains insertion order of elements.
  • Generic: Supports any comparable key and any value type.
  • Efficient: O(1) for Set, Get, Delete.
  • Iteration: Supports range iterator.
  • JSON: Supports JSON marshaling/unmarshaling, preserving order.
  • Sorting: Provides in-place sorting capabilities.

Installation

go get github.com/bycigo/omap

Usage

Creating a omap
// creating by omap.New()
m := omap.New[string, any]()

// with initial capacity
m := omap.Make[string, any](10)
Basic Operations
Set & Get & Has
m.Set("foo", 1)
m.Set("bar", 2)

added := m.TrySet("foo", 3) // added will be false, because "foo" already exists
added := m.TrySet("baz", 3) // added will be true, because "baz" does not exist

if val := m.Get("foo"); ok {
	fmt.Println(val)
}

if val, ok := m.TryGet("foo"); ok {
	fmt.Println(val)
}
if val, ok := m.TryGet("x"); !ok {
	fmt.Println("Key 'x' does not exist")
}

if m.Has("bar") {
	fmt.Println("Key 'bar' exists")
}
Delete & Clear
m.Delete("foo") // Removes "foo"
m.Clear()	   // Removes all elements
Length
fmt.Println(m.Len()) // Returns number of elements
Iteration

Iterate over key-value pairs in insertion order:

for k, v := range m.All() {
	fmt.Printf("%s: %d\n", k, v)
}
Keys & Values

Retrieve all keys or values as a slice, maintaining the current order:

keys := m.Keys()	 // Returns []K
values := m.Values() // Returns []V
Merging Maps

Merge other omap instances into the current one:

m1 := omap.New[string, int]()
m1.Set("a", 1)

m2 := omap.New[string, int]()
m2.Set("b", 2)

m1.Merge(m2)
// m1 now contains a:1, b:2
Reversing Maps

Reverse the order of key-value pairs in-place:

m := omap.New[string, int]()
m.Set("a", 1)
m.Set("b", 2)

m.Reverse()

fmt.Println(m.Keys())   // Output: [b a]
fmt.Println(m.Values()) // Output: [2 1]
Sorting

omap provides in-place sorting methods, but requires keys to be cmp.Ordered.

// Sort in ascending order
omap.Sort(m)

// Sort in descending order
omap.SortDesc(m)

// Sort with a custom comparison function
omap.SortFunc(m, func(k1, k2 string) int {
	// Example: sort by length of keys
	return len(k1) - len(k2)
})
JSON Serialization

omap implements json.Marshaler and json.Unmarshaler interfaces, ensuring JSON objects preserve key order during both marshaling and unmarshaling.

// Marshal
data, err := json.Marshal(m)
// Output: {"foo":1,"bar":2}

// Unmarshal
err := json.Unmarshal(data, m)

Documentation

Overview

Package omap provides an ordered map implementation for Go.

Unlike Go's standard map, omap maintains the insertion order of keys. It leverages Go iterators (iter.Seq2) and supports generic key-value types.

Features

  • Ordered: Maintains insertion order of elements
  • Generic: Supports any comparable key and any value type
  • Efficient: O(1) time complexity for Set, Get, Delete, and Has operations
  • Iteration: Supports range iterator via All() method
  • JSON: Supports JSON marshaling/unmarshaling, preserving key order
  • Sorting: Provides in-place sorting capabilities

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Sort

func Sort[K cmp.Ordered, V any](m *Map[K, V])

Sort sorts the map in ascending order of keys.

Example
m := New[string, int]()
m.Set("c", 3)
m.Set("a", 1)
m.Set("b", 2)

Sort(m)
fmt.Println(m.Keys())
Output:

[a b c]

func SortDesc

func SortDesc[K cmp.Ordered, V any](m *Map[K, V])

SortDesc sorts the map in descending order of keys.

Example
m := New[string, int]()
m.Set("a", 1)
m.Set("c", 3)
m.Set("b", 2)

SortDesc(m)
fmt.Println(m.Keys())
Output:

[c b a]

func SortFunc

func SortFunc[K cmp.Ordered, V any](m *Map[K, V], compare func(k1, k2 K) int)

SortFunc sorts the map using a custom comparison function for keys.

Example
m := New[string, int]()
m.Set("apple", 1)
m.Set("banana", 2)
m.Set("cherry", 3)

// Sort by length of keys descending
SortFunc(m, func(k1, k2 string) int {
	return len(k2) - len(k1)
})
fmt.Println(m.Keys())
Output:

[banana cherry apple]

Types

type Map

type Map[K comparable, V any] struct {
	// contains filtered or unexported fields
}

Map represents an ordered map that maintains elements in the order of their insertion.

func Make

func Make[K comparable, V any](capacity int) *Map[K, V]

Make creates and returns a new Map instance with the specified capacity.

func New

func New[K comparable, V any]() *Map[K, V]

New creates and returns a new Map instance.

Example
m := New[string, int]()
m.Set("foo", 1)
fmt.Println(m.Len())
Output:

1

func (*Map[K, V]) All

func (m *Map[K, V]) All() iter.Seq2[K, V]

All returns an iterator over the map's entries in insertion order.

Example
m := New[string, int]()
m.Set("one", 1)
m.Set("two", 2)
m.Set("three", 3)

for k, v := range m.All() {
	fmt.Printf("%s: %d\n", k, v)
}
Output:

one: 1
two: 2
three: 3

func (*Map[K, V]) Clear

func (m *Map[K, V]) Clear()

Clear removes all key-value pairs from the map.

Example
m := New[string, int]()
m.Set("a", 1)
m.Clear()
fmt.Println(m.Len())
Output:

0

func (*Map[K, V]) Delete

func (m *Map[K, V]) Delete(keys ...K)

Delete removes the key-value pair associated with the given key from the map. It is no-op if the key does not exist.

Example
m := New[string, int]()
m.Set("a", 1)
m.Set("b", 2)
m.Set("c", 3)

m.Delete("b")
fmt.Println(m.Keys())
Output:

[a c]

func (*Map[K, V]) Get

func (m *Map[K, V]) Get(key K) (value V)

Get retrieves the value associated with the given key.

Example
m := New[string, string]()
m.Set("greet", "hello")

val := m.Get("greet")
fmt.Println(val)
Output:

hello

func (*Map[K, V]) Has

func (m *Map[K, V]) Has(key K) bool

Has checks if the given key exists in the map.

Example
m := New[string, int]()
m.Set("x", 42)

fmt.Println(m.Has("x"))
fmt.Println(m.Has("y"))
Output:

true
false

func (*Map[K, V]) Keys

func (m *Map[K, V]) Keys() []K

Keys returns a slice of all keys in the map, in the order they were inserted.

Example
m := New[string, int]()
m.Set("foo", 1)
m.Set("bar", 2)
fmt.Println(m.Keys())
Output:

[foo bar]

func (*Map[K, V]) Len

func (m *Map[K, V]) Len() int

Len returns the number of key-value pairs in the map.

Example
m := New[string, int]()
fmt.Println(m.Len())
m.Set("a", 1)
fmt.Println(m.Len())
Output:

0
1

func (*Map[K, V]) MarshalJSON

func (m *Map[K, V]) MarshalJSON() ([]byte, error)

MarshalJSON handles JSON marshaling for the Map.

Example
m := New[string, int]()
m.Set("foo", 1)
m.Set("bar", 2)

data, _ := json.Marshal(m)
fmt.Println(string(data))
Output:

{"foo":1,"bar":2}

func (*Map[K, V]) Merge

func (m *Map[K, V]) Merge(target ...*Map[K, V])

Merge merges the key-value pairs from the target maps into the current map.

Example
m1 := New[string, int]()
m1.Set("a", 1)

m2 := New[string, int]()
m2.Set("b", 2)
m2.Set("c", 3)

m1.Merge(m2)
fmt.Println(m1.Keys())
Output:

[a b c]

func (*Map[K, V]) Reverse

func (m *Map[K, V]) Reverse()

Reverse reverses the order of elements in the map.

Example
m := New[string, int]()
m.Set("a", 1)
m.Set("b", 2)
m.Set("c", 3)

m.Reverse()
fmt.Println(m.Keys())
fmt.Println(m.Values())
Output:

[c b a]
[3 2 1]

func (*Map[K, V]) Set

func (m *Map[K, V]) Set(key K, value V)

Set adds a key-value pair to the map. If the key already exists, its value is updated. If the key does not exist, it is appended to the end of the insertion order list.

Example
m := New[string, int]()
m.Set("first", 10)
m.Set("second", 20)
// Update existing
m.Set("first", 30)

fmt.Println(m.Keys())
Output:

[first second]

func (*Map[K, V]) TryGet

func (m *Map[K, V]) TryGet(key K) (value V, ok bool)

TryGet retrieves the value associated with the given key. It returns the value and true if the key exists, otherwise the zero value and false.

Example
m := New[string, string]()
m.Set("key", "value")

if val, ok := m.TryGet("key"); ok {
	fmt.Println(val)
}
if _, ok := m.TryGet("missing"); !ok {
	fmt.Println("missing key")
}
Output:

value
missing key

func (*Map[K, V]) TrySet

func (m *Map[K, V]) TrySet(key K, value V) bool

TrySet adds a key-value pair to the map only if the key does not already exist. It returns true if the key-value pair was added, and false if the key already exists.

Example
m := New[string, int]()
m.Set("foo", 1)

fooAdded := m.TrySet("foo", 2)
fmt.Println(fooAdded)
fmt.Println(m.Get("foo"))

barAdded := m.TrySet("bar", 3)
fmt.Println(barAdded)
fmt.Println(m.Get("bar"))
Output:

false
1
true
3

func (*Map[K, V]) UnmarshalJSON

func (m *Map[K, V]) UnmarshalJSON(data []byte) error

UnmarshalJSON handles JSON unmarshaling for the Map.

Example
jsonStr := `{"foo":1,"bar":2,"baz":3}`
m := New[string, int]()

_ = json.Unmarshal([]byte(jsonStr), m)
fmt.Println(m.Keys())
Output:

[foo bar baz]

func (*Map[K, V]) Values

func (m *Map[K, V]) Values() []V

Values returns a slice of all values in the map, in the order their keys were inserted.

Example
m := New[string, int]()
m.Set("foo", 1)
m.Set("bar", 2)
fmt.Println(m.Values())
Output:

[1 2]

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL