Documentation
¶
Overview ¶
Package maps provides generic map utilities, including a case-insensitive map implementation.
Index ¶
- Variables
- func ToGoMap[K comparable, V any](m Map[Key[K], V]) map[K]V
- type CaseInsensitiveMap
- func (s *CaseInsensitiveMap[V]) Add(key string, value V)
- func (s *CaseInsensitiveMap[V]) AddAll(keyValueMap map[string]V)
- func (s *CaseInsensitiveMap[V]) Clear()
- func (s *CaseInsensitiveMap[V]) Clone() *CaseInsensitiveMap[V]
- func (s *CaseInsensitiveMap[V]) ContainsKey(key string, caseSensitive bool) (bool, string)
- func (s *CaseInsensitiveMap[V]) Filter(predicate func(string, V) bool) *CaseInsensitiveMap[V]
- func (s *CaseInsensitiveMap[V]) Get(key string, caseSensitive bool) (string, V, bool)
- func (s *CaseInsensitiveMap[V]) GetAll() map[string]V
- func (s *CaseInsensitiveMap[V]) IsEmpty() bool
- func (s *CaseInsensitiveMap[V]) Keys() []string
- func (s *CaseInsensitiveMap[V]) Merge(other *CaseInsensitiveMap[V])
- func (s *CaseInsensitiveMap[V]) MergeAll(others ...*CaseInsensitiveMap[V])
- func (s *CaseInsensitiveMap[V]) Remove(key string)
- func (s *CaseInsensitiveMap[V]) RemoveAll(keys ...string)
- func (s *CaseInsensitiveMap[V]) Size() int
- func (s *CaseInsensitiveMap[V]) Values() []V
- type Key
- type KeyValuePair
- type Map
- func FromGoMap[K comparable, V any](m map[K]V, hash hashing.HashFunc) Map[Key[K], V]
- func FromSet[K collectable.Collectable[K], V any](s set.Set[K], getValue func(key K) V) Map[K, V]
- func NewDefaultMap[K any, V any](storageMap Map[K, V], getDefaultValue func(K) (V, error)) Map[K, V]
- func NewDefaultZeroMap[K any, V any](storageMap Map[K, V]) Map[K, V]
- func NewHashMap[K collectable.Collectable[K], V any](hash hashing.HashFunc) Map[K, V]
- func NewHashMapWithSize[K collectable.Collectable[K], V any](hash hashing.HashFunc, size int) Map[K, V]
- func NewRedBlackTreeMap[K sortable.Sortable[K], V any]() Map[K, V]
- func NewThreadSafeMap[K any, V any](m Map[K, V]) Map[K, V]
- type OrderedMap
- func FromOrderedSet[K collectable.Collectable[K], V any](s set.OrderedSet[K], getValue func(key K) V) OrderedMap[K, V]
- func NewDefaultOrderedMap[K any, V any](storageMap OrderedMap[K, V], getDefaultValue func(K) (V, error)) OrderedMap[K, V]
- func NewDefaultZeroOrderedMap[K any, V any](storageMap OrderedMap[K, V]) OrderedMap[K, V]
- func NewOrderedHashMap[K collectable.Collectable[K], V any](hash hashing.HashFunc) OrderedMap[K, V]
- func NewThreadSafeOrderedMap[K any, V any](m OrderedMap[K, V]) OrderedMap[K, V]
Constants ¶
This section is empty.
Variables ¶
var ErrNoDefaultValue = errors.New("no default value for this key")
ErrNoDefaultValue is returned by the default value function when it cannot or chooses not to provide a default value for a given key. When this error is returned, the defaultMap will not add the key to the map and will behave as if the key simply doesn't exist.
Functions ¶
func ToGoMap ¶
func ToGoMap[K comparable, V any](m Map[Key[K], V]) map[K]V
ToGoMap converts an amp-common Map to a standard Go map. It extracts all key-value pairs from the Map and returns them in a native Go map[K]V.
Returns nil if the input map is nil. The iteration order is non-deterministic for standard maps and follows insertion order for ordered maps.
Example:
ampMap := NewHashMap[Key[string], int](hashing.Sha256)
ampMap.Add(Key[string]{Key: "a"}, 1)
goMap := ToGoMap(ampMap)
// goMap is now map[string]int{"a": 1}
Types ¶
type CaseInsensitiveMap ¶
type CaseInsensitiveMap[V any] struct { // contains filtered or unexported fields }
CaseInsensitiveMap is a map that allows both case-sensitive and case-insensitive key lookups. It maintains the original casing of keys while also supporting case-insensitive retrieval. The zero value is not ready to use; use NewCaseInsensitiveMap to create instances.
Example:
m := maps.NewCaseInsensitiveMap(map[string]string{"Content-Type": "application/json"})
key, val, ok := m.Get("content-type", false) // case-insensitive: returns "Content-Type", "application/json", true
key, val, ok := m.Get("Content-Type", true) // case-sensitive: returns "Content-Type", "application/json", true
func NewCaseInsensitiveMap ¶
func NewCaseInsensitiveMap[V any](from map[string]V) *CaseInsensitiveMap[V]
NewCaseInsensitiveMap creates a new CaseInsensitiveMap initialized with the provided key-value pairs. Pass nil or an empty map to create an empty map.
func (*CaseInsensitiveMap[V]) Add ¶
func (s *CaseInsensitiveMap[V]) Add(key string, value V)
Add adds a key-value pair to the map. If a key with different casing already exists, it removes the old entry first and adds the new one with the provided casing. This ensures only one entry per case-insensitive key exists, with the most recently added casing preserved.
func (*CaseInsensitiveMap[V]) AddAll ¶
func (s *CaseInsensitiveMap[V]) AddAll(keyValueMap map[string]V)
AddAll adds multiple key-value pairs to the map. This is a convenience method that calls Add for each entry in the provided map.
func (*CaseInsensitiveMap[V]) Clear ¶
func (s *CaseInsensitiveMap[V]) Clear()
Clear removes all key-value pairs from the map. After calling Clear, the map is empty but still usable.
func (*CaseInsensitiveMap[V]) Clone ¶
func (s *CaseInsensitiveMap[V]) Clone() *CaseInsensitiveMap[V]
Clone creates a deep copy of the map. Returns nil if the receiver is nil.
func (*CaseInsensitiveMap[V]) ContainsKey ¶
func (s *CaseInsensitiveMap[V]) ContainsKey(key string, caseSensitive bool) (bool, string)
ContainsKey checks if a key exists in the map. The caseSensitive parameter determines whether the lookup is case-sensitive. Returns whether the key exists and the original casing of the stored key (if found).
func (*CaseInsensitiveMap[V]) Filter ¶
func (s *CaseInsensitiveMap[V]) Filter(predicate func(string, V) bool) *CaseInsensitiveMap[V]
Filter returns a new map containing only the key-value pairs that satisfy the predicate. The predicate receives the original key (with preserved casing) and value.
func (*CaseInsensitiveMap[V]) Get ¶
func (s *CaseInsensitiveMap[V]) Get(key string, caseSensitive bool) (string, V, bool)
Get retrieves a value from the map by key. The caseSensitive parameter determines whether the lookup is case-sensitive. Returns the original key (with preserved casing), value, and whether the key was found. When caseSensitive is false, returns the original casing of the stored key.
Example:
m.Add("Content-Type", "application/json")
key, val, ok := m.Get("content-type", false) // returns "Content-Type", "application/json", true
key, val, ok := m.Get("content-type", true) // returns "content-type", zero, false
nolint:ireturn
func (*CaseInsensitiveMap[V]) GetAll ¶
func (s *CaseInsensitiveMap[V]) GetAll() map[string]V
GetAll returns all key-value pairs in the map with original key casing preserved. Returns nil if the map is empty.
func (*CaseInsensitiveMap[V]) IsEmpty ¶
func (s *CaseInsensitiveMap[V]) IsEmpty() bool
IsEmpty returns true if the map contains no key-value pairs.
func (*CaseInsensitiveMap[V]) Keys ¶
func (s *CaseInsensitiveMap[V]) Keys() []string
Keys returns all keys in the map with original casing preserved. The order of keys is non-deterministic.
func (*CaseInsensitiveMap[V]) Merge ¶
func (s *CaseInsensitiveMap[V]) Merge(other *CaseInsensitiveMap[V])
Merge merges another map into this map. Existing keys (case-insensitive match) are replaced with values from the other map.
func (*CaseInsensitiveMap[V]) MergeAll ¶
func (s *CaseInsensitiveMap[V]) MergeAll(others ...*CaseInsensitiveMap[V])
MergeAll merges multiple maps into this map. Maps are merged in order, with later maps overwriting earlier ones for duplicate keys.
func (*CaseInsensitiveMap[V]) Remove ¶
func (s *CaseInsensitiveMap[V]) Remove(key string)
Remove removes a key-value pair from the map using case-insensitive lookup. If the key doesn't exist, this is a no-op.
func (*CaseInsensitiveMap[V]) RemoveAll ¶
func (s *CaseInsensitiveMap[V]) RemoveAll(keys ...string)
RemoveAll removes multiple key-value pairs from the map. This is a convenience method that calls Remove for each provided key.
func (*CaseInsensitiveMap[V]) Size ¶
func (s *CaseInsensitiveMap[V]) Size() int
Size returns the number of key-value pairs in the map.
func (*CaseInsensitiveMap[V]) Values ¶
func (s *CaseInsensitiveMap[V]) Values() []V
Values returns all values in the map. The order of values is non-deterministic.
type Key ¶
type Key[T comparable] struct { Key T }
Key is a generic wrapper type that adapts any comparable type to be used as a map key. It implements the collectable.Collectable interface, making comparable types compatible with the Map interface that requires hashable and comparable keys.
This type bridges the gap between Go's built-in comparable constraint and the amp-common collectable.Collectable interface, allowing standard Go types (int, string, etc.) to be used with hash-based maps.
Example:
// Wrapping a string
key := Key[string]{Key: "my-key"}
// Using with a hash map
m := NewHashMap[Key[string], int](hashing.Sha256)
m.Add(Key[string]{Key: "count"}, 42)
func (Key[T]) Equals ¶
Equals compares this Key with another Key for equality. Two Keys are equal if their wrapped values are equal according to Go's == operator.
func (Key[T]) UpdateHash ¶
UpdateHash writes the key's hash representation to the provided hash.Hash. It converts the comparable key to a collectable.Collectable and delegates hashing to it. This allows any comparable type to participate in the hashing process.
type KeyValuePair ¶
KeyValuePair is a generic key-value pair struct used to represent entries in maps. It's particularly used by the OrderedMap.Seq() method to provide both the key and value in a single return value, along with an index to indicate insertion order.
The Key must implement the collectable.Collectable interface (hashable and comparable), while the Value can be any type.
Example:
// Returned by OrderedMap iteration
for i, entry := range orderedMap.Seq() {
fmt.Printf("Index: %d, Key: %v, Value: %v\n", i, entry.Key, entry.Value)
}
type Map ¶
type Map[K any, V any] interface { // Get retrieves the value for the given key from the hash map. // If the key exists, returns the value with found=true. If the key doesn't exist, returns // a zero value with found=false. // Returns ErrHashCollision if a different key with the same hash exists in the map. Get(key K) (value V, found bool, err error) // GetOrElse retrieves the value for the given key, or returns defaultValue if the key doesn't exist. // Returns ErrHashCollision if a different key with the same hash exists in the map. GetOrElse(key K, defaultValue V) (value V, err error) // Add inserts or updates a key-value pair in the map. // If the key already exists, its value is replaced. // Returns ErrHashCollision if the hash function produces a collision with a different key. Add(key K, value V) error // Remove deletes the key-value pair from the map. // If the key doesn't exist, this is a no-op and returns nil. // Returns ErrHashCollision if the hash function produces a collision with a different key. Remove(key K) error // Clear removes all key-value pairs from the map, leaving it empty. Clear() // Contains checks if the given key exists in the map. // Returns true if the key exists, false otherwise. // Returns ErrHashCollision if the hash function produces a collision with a different key. Contains(key K) (bool, error) // Size returns the number of key-value pairs currently stored in the map. Size() int // Seq returns an iterator for ranging over all key-value pairs in the map. // The iteration order is non-deterministic. This method is compatible with // Go 1.23+ range-over-func syntax: for key, value := range map.Seq() { ... } Seq() iter.Seq2[K, V] // Union creates a new map containing all key-value pairs from both this map and other. // If a key exists in both maps, the value from other takes precedence. // Returns ErrHashCollision if any hash collision occurs during the operation. Union(other Map[K, V]) (Map[K, V], error) // Intersection creates a new map containing only key-value pairs whose keys exist in both maps. // The values are taken from this map, not from other. // Returns ErrHashCollision if any hash collision occurs during the operation. Intersection(other Map[K, V]) (Map[K, V], error) // Clone creates a shallow copy of the map, duplicating its structure and entries. // The keys and values themselves are not deep-copied; they are referenced as-is. // Returns a new Map instance with the same entries. Clone() Map[K, V] // HashFunction returns the hash function used by this map. // This allows callers to inspect the hash function or create compatible maps // that use the same hashing strategy, ensuring consistent key hashing across // different map instances. // // Example use cases: // - Creating a new map with the same hash function // - Verifying two maps use compatible hash functions before merging // - Debugging hash collision issues HashFunction() hashing.HashFunc // Keys returns a set containing all keys from the map. // The returned set is a new instance and modifications to it do not affect the original map. Keys() set.Set[K] // ForEach applies the given function to each key-value pair in the map. // The iteration order is non-deterministic. This method is used for side effects only // and does not return a value. ForEach(f func(key K, value V)) // ForAll tests whether a predicate holds for all key-value pairs in the map. // Returns true if the predicate returns true for all entries, false otherwise. // The iteration stops early if the predicate returns false for any entry. ForAll(predicate func(key K, value V) bool) bool // Filter creates a new map containing only key-value pairs for which the predicate returns true. // The predicate function is applied to each entry, and only matching entries are included // in the result map. Filter(predicate func(key K, value V) bool) Map[K, V] // FilterNot creates a new map containing only key-value pairs for which the predicate returns false. // This is the inverse of Filter - it excludes entries where the predicate returns true. FilterNot(predicate func(key K, value V) bool) Map[K, V] // Map transforms all key-value pairs in the map by applying the given function to each entry. // The function receives each key-value pair and returns a new key-value pair. // Returns a new map containing the transformed entries. // Note: If the transformation produces duplicate keys, the behavior depends on insertion order. Map(f func(key K, value V) (K, V)) Map[K, V] // FlatMap applies the given function to each key-value pair and flattens the results into a single map. // Each function call returns a map, and all returned maps are merged together. // Returns a new map containing all entries from the flattened results. // If duplicate keys exist across multiple results, later values take precedence. FlatMap(f func(key K, value V) Map[K, V]) Map[K, V] // Exists tests whether at least one key-value pair in the map satisfies the given predicate. // Returns true if the predicate returns true for any entry, false otherwise. // The iteration stops early as soon as a matching entry is found. Exists(predicate func(key K, value V) bool) bool // FindFirst searches for the first key-value pair that satisfies the given predicate. // Returns Some(KeyValuePair) if a matching entry is found, None otherwise. // The iteration order is non-deterministic, so "first" is not guaranteed to be consistent. FindFirst(predicate func(key K, value V) bool) optional.Value[KeyValuePair[K, V]] }
Map is a generic hash map interface for storing key-value pairs where keys must be both hashable and comparable. It provides set-like operations (Union, Intersection) in addition to standard map operations. All methods that modify the map or query for keys may return ErrHashCollision if the hash function produces collisions.
Keys must implement the collectable.Collectable interface, which ensures they can be hashed for efficient lookup and compared for equality to resolve hash collisions.
Thread-safety: Implementations are not guaranteed to be thread-safe unless explicitly documented. Concurrent access must be synchronized by the caller.
func FromGoMap ¶
FromGoMap converts a standard Go map to an amp-common Map implementation. It creates a new HashMap and populates it with all key-value pairs from the input map.
The hash parameter specifies the hash function to use for the map (e.g., hashing.Sha256). Returns nil if the input map is nil.
Panics if adding a key-value pair fails due to a hash collision. This should be rare with a good hash function like SHA-256.
Example:
goMap := map[string]int{"a": 1, "b": 2}
ampMap := FromGoMap(goMap, hashing.Sha256)
// ampMap can now use Map interface methods
func FromSet ¶
func FromSet[K collectable.Collectable[K], V any](s set.Set[K], getValue func(key K) V) Map[K, V]
FromSet converts a Set to a Map by applying a value function to each key. The getValue function is called for each key in the set to produce the corresponding value. The resulting map uses the same hash function as the input set and is pre-allocated to the set's size.
Returns nil if the input set is nil.
The iteration order is non-deterministic as it depends on the set's internal iteration order.
Example:
// Create a map from a set of strings to their lengths
stringSet := set.NewSet[String](hashFunc)
stringSet.Add("hello")
stringSet.Add("world")
m := FromSet(stringSet, func(s String) int { return len(s.Value) })
// m contains: {"hello": 5, "world": 5}
func NewDefaultMap ¶
func NewDefaultMap[K any, V any]( storageMap Map[K, V], getDefaultValue func(K) (V, error), ) Map[K, V]
NewDefaultMap creates a Map that automatically generates default values for missing keys. When Get or Contains is called with a key that doesn't exist, the getDefaultValue function is invoked to generate a value, which is then added to the map and returned.
The getDefaultValue function should return ErrNoDefaultValue when it cannot or chooses not to provide a default value. In that case, the map behaves as if the key doesn't exist.
If storageMap is already a defaultMap, this function clones it and replaces the default value function with the new one provided.
Parameters:
- storageMap: The underlying Map implementation to use for storage
- getDefaultValue: Function that generates default values for missing keys
Example:
// Create a map that defaults to empty strings for missing keys
m := maps.NewDefaultMap(
maps.NewHashMap[MyKey, string](hashFunc),
func(k MyKey) (string, error) {
return "", nil
},
)
value, found, _ := m.Get(missingKey) // Returns ("", true, nil) and adds to map
// Create a map that refuses to provide defaults
m2 := maps.NewDefaultMap(
maps.NewHashMap[MyKey, string](hashFunc),
func(k MyKey) (string, error) {
return "", maps.ErrNoDefaultValue
},
)
value, found, _ := m2.Get(missingKey) // Returns ("", false, nil) without adding
func NewDefaultZeroMap ¶
NewDefaultZeroMap creates a Map that automatically returns zero values for missing keys. This is a convenience wrapper around NewDefaultMap that uses the zero value of type V as the default for all missing keys.
When Get or Contains is called with a key that doesn't exist in the map, the zero value for type V is generated, added to the map, and returned. The key is then considered to exist in the map going forward.
This is particularly useful for:
- Counter maps: map[string]int where missing keys should start at 0
- Collection maps: map[string][]T where missing keys should start as empty slices
- Boolean flags: map[string]bool where missing keys should default to false
- Optional value maps: map[string]*T where missing keys should be nil
Unlike NewDefaultMap which requires a custom function, NewDefaultZeroMap always succeeds in providing a default value - it never returns ErrNoDefaultValue.
Parameters:
- storageMap: The underlying Map implementation to use for storage. This can be any Map implementation (HashMap, SortedMap, etc.) and determines the storage semantics.
Returns:
- A Map that automatically generates zero values for missing keys and adds them to the map.
Example usage:
// Create a counter map where missing keys default to 0
counters := maps.NewDefaultZeroMap[StringKey, int](
maps.NewHashMap[StringKey, int](hashFunc),
)
count, _, _ := counters.Get(key) // Returns (0, true, nil) and adds key->0 to map
// Create a map of slices where missing keys default to empty slices
lists := maps.NewDefaultZeroMap[StringKey, []string](
maps.NewHashMap[StringKey, []string](hashFunc),
)
items, _, _ := lists.Get(key) // Returns ([]string{}, true, nil) and adds key->[] to map
// Create a boolean flag map where missing keys default to false
flags := maps.NewDefaultZeroMap[StringKey, bool](
maps.NewHashMap[StringKey, bool](hashFunc),
)
enabled, _, _ := flags.Get(key) // Returns (false, true, nil) and adds key->false to map
func NewHashMap ¶
func NewHashMap[K collectable.Collectable[K], V any](hash hashing.HashFunc) Map[K, V]
NewHashMap creates a new hash-based Map implementation using the provided hash function. The hash function must produce consistent hash values for equal keys and should minimize collisions to avoid ErrHashCollision errors during operations.
The returned map is not thread-safe. Concurrent access must be synchronized by the caller.
Example:
// Using a custom hash function
m := maps.NewMap[MyKey, string](func(k hashing.Hashable) (string, error) {
return k.Hash(), nil
})
m.Add(key, "value")
func NewHashMapWithSize ¶
func NewHashMapWithSize[K collectable.Collectable[K], V any](hash hashing.HashFunc, size int) Map[K, V]
NewHashMapWithSize creates a new hash-based Map implementation with pre-allocated capacity. This function is similar to NewHashMap but allows specifying an initial capacity hint to optimize memory allocation when the expected map size is known in advance.
The size parameter pre-allocates space for approximately 'size' entries, reducing the need for memory reallocation during initial insertions. This can improve performance when building large maps. The map will still grow dynamically if more entries are added beyond the initial size.
The hash function must produce consistent hash values for equal keys and should minimize collisions to avoid ErrHashCollision errors during operations.
The returned map is not thread-safe. Concurrent access must be synchronized by the caller.
Use this function when:
- You know the approximate number of entries in advance
- You're building a large map and want to avoid multiple reallocations
- Performance during initial population is critical
Example:
// Creating a map for 1000 expected entries
m := maps.NewHashMapWithSize[MyKey, string](hashFunc, 1000)
for i := 0; i < 1000; i++ {
m.Add(keys[i], values[i])
}
func NewRedBlackTreeMap ¶
NewRedBlackTreeMap creates a new empty red-black tree map. The map maintains O(log n) performance for all operations by keeping the tree balanced.
func NewThreadSafeMap ¶
NewThreadSafeMap wraps an existing Map implementation with thread-safe access using sync.RWMutex. It provides concurrent read/write access to the underlying map while preserving the Map interface.
The wrapper uses read-write locks to allow multiple concurrent readers or exclusive writer access. Write operations (Add, Remove, Clear) acquire exclusive locks, while read operations (Contains, Size, Seq, Union, Intersection, Clone) use shared read locks for better concurrency.
Example usage:
unsafeMap := maps.New[string, int]()
safeMap := maps.NewThreadSafeMap(unsafeMap)
safeMap.Add("key", 42) // thread-safe
type OrderedMap ¶
type OrderedMap[K any, V any] interface { // Get retrieves the value for the given key from the hash map. // If the key exists, returns the value with found=true. If the key doesn't exist, returns // a zero value with found=false. // Returns ErrHashCollision if a different key with the same hash exists in the map. Get(key K) (value V, found bool, err error) // GetOrElse retrieves the value for the given key, or returns defaultValue if the key doesn't exist. // Returns ErrHashCollision if a different key with the same hash exists in the map. GetOrElse(key K, defaultValue V) (value V, err error) // Add inserts or updates a key-value pair in the map. // If the key already exists, its value is replaced without changing the insertion order. // If the key is new, it's appended to the end of the insertion order. // Returns ErrHashCollision if the hash function produces a collision with a different key. Add(key K, value V) error // Remove deletes the key-value pair from the map. // If the key doesn't exist, this is a no-op and returns nil. // Returns ErrHashCollision if the hash function produces a collision with a different key. Remove(key K) error // Clear removes all key-value pairs from the map, leaving it empty. Clear() // Contains checks if the given key exists in the map. // Returns true if the key exists, false otherwise. // Returns ErrHashCollision if the hash function produces a collision with a different key. Contains(key K) (bool, error) // Size returns the number of key-value pairs currently stored in the map. Size() int // Seq returns an iterator for ranging over all key-value pairs in insertion order. // The iterator yields (index, KeyValuePair) tuples where index represents the insertion order. // This method is compatible with Go 1.23+ range-over-func syntax: // for i, entry := range map.Seq() { ... } Seq() iter.Seq2[int, KeyValuePair[K, V]] // Union creates a new map containing all key-value pairs from both this map and other. // Entries from this map are added first (preserving their order), followed by entries from other. // If a key exists in both maps, the value from other takes precedence, but the key maintains // its original position from this map. // Returns ErrHashCollision if any hash collision occurs during the operation. Union(other OrderedMap[K, V]) (OrderedMap[K, V], error) // Intersection creates a new map containing only key-value pairs whose keys exist in both maps. // The values are taken from this map, not from other, and the insertion order is preserved // from this map. // Returns ErrHashCollision if any hash collision occurs during the operation. Intersection(other OrderedMap[K, V]) (OrderedMap[K, V], error) // Clone creates a shallow copy of the map, duplicating its structure, entries, and insertion order. // The keys and values themselves are not deep-copied; they are referenced as-is. // Returns a new OrderedMap instance with the same entries in the same order. Clone() OrderedMap[K, V] // HashFunction returns the hash function used by this ordered map. // This allows callers to inspect the hash function or create compatible ordered maps // that use the same hashing strategy, ensuring consistent key hashing across // different map instances. // // Example use cases: // - Creating a new ordered map with the same hash function // - Verifying two ordered maps use compatible hash functions before merging // - Debugging hash collision issues HashFunction() hashing.HashFunc // Keys returns a set containing all keys from the map, in insertion order. // The returned set is a new instance and modifications to it do not affect the original map. Keys() set.OrderedSet[K] // ForEach applies the given function to each key-value pair in the map. // The iteration order is non-deterministic. This method is used for side effects only // and does not return a value. ForEach(f func(key K, value V)) // ForAll tests whether a predicate holds for all key-value pairs in the map. // Returns true if the predicate returns true for all entries, false otherwise. // The iteration stops early if the predicate returns false for any entry. ForAll(predicate func(key K, value V) bool) bool // Filter creates a new map containing only key-value pairs for which the predicate returns true. // The predicate function is applied to each entry, and only matching entries are included // in the result map. Filter(predicate func(key K, value V) bool) OrderedMap[K, V] // FilterNot creates a new map containing only key-value pairs for which the predicate returns false. // This is the inverse of Filter - it excludes entries where the predicate returns true. FilterNot(predicate func(key K, value V) bool) OrderedMap[K, V] // Map transforms all key-value pairs in the map by applying the given function to each entry. // The function receives each key-value pair and returns a new key-value pair. // Returns a new map containing the transformed entries. // Note: If the transformation produces duplicate keys, the behavior depends on insertion order. Map(f func(key K, value V) (K, V)) OrderedMap[K, V] // FlatMap applies the given function to each key-value pair and flattens the results into a single map. // Each function call returns a map, and all returned maps are merged together. // Returns a new map containing all entries from the flattened results. // If duplicate keys exist across multiple results, later values take precedence. FlatMap(f func(key K, value V) OrderedMap[K, V]) OrderedMap[K, V] // Exists tests whether at least one key-value pair in the map satisfies the given predicate. // Returns true if the predicate returns true for any entry, false otherwise. // The iteration stops early as soon as a matching entry is found. Exists(predicate func(key K, value V) bool) bool // FindFirst searches for the first key-value pair that satisfies the given predicate. // Returns Some(KeyValuePair) if a matching entry is found, None otherwise. // The iteration order is non-deterministic, so "first" is not guaranteed to be consistent. FindFirst(predicate func(key K, value V) bool) optional.Value[KeyValuePair[K, V]] }
OrderedMap is a generic ordered hash map interface for storing key-value pairs where keys must be both hashable and comparable. Unlike the standard Map interface, OrderedMap preserves insertion order when iterating. It provides set-like operations (Union, Intersection) in addition to standard map operations. All methods that modify the map or query for keys may return ErrHashCollision if the hash function produces collisions.
Keys must implement the collectable.Collectable interface, which ensures they can be hashed for efficient lookup and compared for equality to resolve hash collisions.
Thread-safety: Implementations are not guaranteed to be thread-safe unless explicitly documented. Concurrent access must be synchronized by the caller.
func FromOrderedSet ¶
func FromOrderedSet[K collectable.Collectable[K], V any](s set.OrderedSet[K], getValue func(key K) V) OrderedMap[K, V]
FromOrderedSet converts an OrderedSet to an OrderedMap by applying a value function to each key. The getValue function is called for each key in the ordered set to produce the corresponding value. The resulting ordered map uses the same hash function as the input set and preserves the insertion order.
Returns nil if the input set is nil.
The iteration follows the insertion order of the set, and the resulting map maintains this same order.
Example:
// Create an ordered map from an ordered set of strings to their lengths
stringSet := set.NewOrderedSet[String](hashFunc)
stringSet.Add("hello")
stringSet.Add("world")
m := FromOrderedSet(stringSet, func(s String) int { return len(s.Value) })
// m contains: {"hello": 5, "world": 5} in insertion order
func NewDefaultOrderedMap ¶
func NewDefaultOrderedMap[K any, V any]( storageMap OrderedMap[K, V], getDefaultValue func(K) (V, error), ) OrderedMap[K, V]
NewDefaultOrderedMap creates an OrderedMap that automatically generates default values for missing keys. When Get or Contains is called with a key that doesn't exist, the getDefaultValue function is invoked to generate a value, which is then added to the map (at the end of the insertion order) and returned.
The getDefaultValue function should return ErrNoDefaultValue when it cannot or chooses not to provide a default value. In that case, the map behaves as if the key doesn't exist.
If storageMap is already a defaultOrderedMap, this function clones it and replaces the default value function with the new one provided.
Unlike the standard Map, OrderedMap preserves the insertion order of keys. When a default value is generated and added, it's appended to the end of the current insertion order.
Parameters:
- storageMap: The underlying OrderedMap implementation to use for storage
- getDefaultValue: Function that generates default values for missing keys
Example:
// Create an ordered map that defaults to empty strings for missing keys
m := maps.NewDefaultOrderedMap(
maps.NewOrderedHashMap[MyKey, string](hashFunc),
func(k MyKey) (string, error) {
return "", nil
},
)
value, found, _ := m.Get(missingKey) // Returns ("", true, nil) and adds to end
// Create a map that refuses to provide defaults
m2 := maps.NewDefaultOrderedMap(
maps.NewOrderedHashMap[MyKey, string](hashFunc),
func(k MyKey) (string, error) {
return "", maps.ErrNoDefaultValue
},
)
value, found, _ := m2.Get(missingKey) // Returns ("", false, nil) without adding
func NewDefaultZeroOrderedMap ¶
func NewDefaultZeroOrderedMap[K any, V any]( storageMap OrderedMap[K, V], ) OrderedMap[K, V]
NewDefaultZeroOrderedMap creates an OrderedMap that automatically provides zero values for missing keys. This is a convenience wrapper around NewDefaultOrderedMap that uses the zero value of type V as the default value for any key that doesn't exist in the map.
When Get or Contains is called with a key that doesn't exist, the zero value for type V is automatically generated and added to the map (at the end of the insertion order), then returned. This eliminates the need to manually check if a key exists before accessing it.
Unlike NewDefaultOrderedMap, there's no way for this map to refuse providing a default value - it will always succeed in generating a zero value for missing keys. This makes it ideal for use cases where you want default initialization without custom logic.
The map preserves insertion order of keys. When a zero value is auto-generated for a missing key, that key is appended to the end of the current insertion order.
Common zero values by type:
- Numeric types (int, float64, etc.): 0
- Strings: ""
- Booleans: false
- Pointers: nil
- Slices, maps, channels: nil
- Structs: struct with all fields set to their zero values
Parameters:
- storageMap: The underlying OrderedMap implementation to use for storage
Example usage:
// Create an ordered map that defaults to 0 for missing integer keys
m := maps.NewDefaultZeroOrderedMap[string, int](
maps.NewOrderedHashMap[string, int](hashing.NewGoHasher[string]()),
)
value, found, _ := m.Get("missing") // Returns (0, true, nil) and adds key with value 0
// Create an ordered map that defaults to empty strings
m2 := maps.NewDefaultZeroOrderedMap[int, string](
maps.NewOrderedHashMap[int, string](hashing.NewGoHasher[int]()),
)
value, found, _ := m2.Get(42) // Returns ("", true, nil) and adds key 42 with value ""
// Works with structs too - all fields initialized to their zero values
type Config struct {
Enabled bool
Retries int
}
m3 := maps.NewDefaultZeroOrderedMap[string, Config](
maps.NewOrderedHashMap[string, Config](hashing.NewGoHasher[string]()),
)
cfg, found, _ := m3.Get("app") // Returns (Config{Enabled: false, Retries: 0}, true, nil)
func NewOrderedHashMap ¶
func NewOrderedHashMap[K collectable.Collectable[K], V any](hash hashing.HashFunc) OrderedMap[K, V]
NewOrderedHashMap creates a new ordered hash-based OrderedMap implementation using the provided hash function. The hash function must produce consistent hash values for equal keys and should minimize collisions to avoid ErrHashCollision errors during operations.
Unlike the standard Map interface, the returned OrderedMap preserves insertion order when iterating through entries. The iteration order is deterministic and reflects the order in which keys were first added to the map.
The returned map is not thread-safe. Concurrent access must be synchronized by the caller.
Example:
// Using a custom hash function
m := maps.NewOrderedHashMap[MyKey, string](func(k hashing.Hashable) (string, error) {
return k.Hash(), nil
})
m.Add(key1, "first")
m.Add(key2, "second")
// Iteration will always be in order: key1, key2
func NewThreadSafeOrderedMap ¶
func NewThreadSafeOrderedMap[K any, V any](m OrderedMap[K, V]) OrderedMap[K, V]
NewThreadSafeOrderedMap wraps an existing OrderedMap implementation with thread-safe access using sync.RWMutex. It provides concurrent read/write access to the underlying ordered map while preserving the OrderedMap interface.
The wrapper uses read-write locks to allow multiple concurrent readers or exclusive writer access. Write operations (Add, Remove, Clear) acquire exclusive locks, while read operations (Contains, Size, Seq, Union, Intersection, Clone) use shared read locks for better concurrency.
Example usage:
unsafeMap := maps.NewOrderedHashMap[string, int](hashing.Sha256)
safeMap := maps.NewThreadSafeOrderedMap(unsafeMap)
safeMap.Add("key", 42) // thread-safe