133 lines
2.9 KiB
Go
133 lines
2.9 KiB
Go
package extypes
|
|
|
|
import "reflect"
|
|
|
|
// HashMap is a generic wrapper around Go's built-in map type.
|
|
type HashMap[K comparable, V any] map[K]V
|
|
|
|
// NewMapFrom returns a shallow copy of m as a HashMap.
|
|
func NewMapFrom[K comparable, V any](m map[K]V) HashMap[K, V] {
|
|
out := make(HashMap[K, V])
|
|
for k, v := range m {
|
|
out[k] = v
|
|
}
|
|
return out
|
|
}
|
|
|
|
// Len returns the number of entries in m.
|
|
func (m HashMap[K, V]) Len() int { return len(m) }
|
|
|
|
// Add stores val under key and returns m.
|
|
func (m HashMap[K, V]) Add(key K, val V) HashMap[K, V] {
|
|
m[key] = val
|
|
return m
|
|
}
|
|
|
|
// Remove deletes key and returns m.
|
|
func (m HashMap[K, V]) Remove(key K) HashMap[K, V] {
|
|
delete(m, key)
|
|
return m
|
|
}
|
|
|
|
// Get returns the value stored under key.
|
|
func (m HashMap[K, V]) Get(key K) V { return m[key] }
|
|
|
|
// GetOrDefault returns the value stored under key or def if the key is absent.
|
|
func (m HashMap[K, V]) GetOrDefault(key K, def V) V {
|
|
v, ok := m[key]
|
|
if !ok {
|
|
return def
|
|
}
|
|
return v
|
|
}
|
|
|
|
// Contains reports whether key is present in m.
|
|
func (m HashMap[K, V]) Contains(key K) bool {
|
|
_, ok := m[key]
|
|
return ok
|
|
}
|
|
|
|
// IndexKey returns the iteration index of key or -1 when absent.
|
|
// The result depends on Go map iteration order and is therefore not stable.
|
|
func (m HashMap[K, V]) IndexKey(key K) int {
|
|
index := 0
|
|
for k, _ := range m {
|
|
if k == key {
|
|
return index
|
|
}
|
|
index++
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// IndexValue returns the iteration index of value or -1 when absent.
|
|
// The result depends on Go map iteration order and comparison uses
|
|
// reflect.DeepEqual.
|
|
func (m HashMap[K, V]) IndexValue(value V) int {
|
|
index := 0
|
|
for _, v := range m {
|
|
if reflect.DeepEqual(value, v) {
|
|
return index
|
|
}
|
|
index++
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// Keys returns the current keys in unspecified order.
|
|
func (m HashMap[K, V]) Keys() []K {
|
|
keys := make([]K, 0, m.Len())
|
|
for k := range m {
|
|
keys = append(keys, k)
|
|
}
|
|
return keys
|
|
}
|
|
|
|
// Values returns the current values in unspecified order.
|
|
func (m HashMap[K, V]) Values() []V {
|
|
values := make([]V, 0, m.Len())
|
|
for _, v := range m {
|
|
values = append(values, v)
|
|
}
|
|
return values
|
|
}
|
|
|
|
// Items returns keys and values collected in the same iteration order.
|
|
func (m HashMap[K, V]) Items() ([]K, []V) {
|
|
keys := make(Slice[K], 0, m.Len())
|
|
values := make(Slice[V], 0, m.Len())
|
|
for k, v := range m {
|
|
keys = keys.Push(k)
|
|
values = values.Push(v)
|
|
}
|
|
return keys, values
|
|
}
|
|
|
|
// Filter returns a new HashMap containing only entries accepted by f.
|
|
func (m HashMap[K, V]) Filter(f func(K, V) bool) HashMap[K, V] {
|
|
out := make(HashMap[K, V])
|
|
for k, v := range m {
|
|
if !f(k, v) {
|
|
continue
|
|
}
|
|
out[k] = v
|
|
}
|
|
return out
|
|
}
|
|
|
|
// ForEach calls f for every entry and returns m.
|
|
func (m HashMap[K, V]) ForEach(f func(K, V)) HashMap[K, V] {
|
|
for k, v := range m {
|
|
f(k, v)
|
|
}
|
|
return m
|
|
}
|
|
|
|
// Map replaces every value with the result of f and returns m.
|
|
func (m HashMap[K, V]) Map(f func(K, V) V) HashMap[K, V] {
|
|
for k, v := range m {
|
|
m[k] = f(k, v)
|
|
}
|
|
return m
|
|
}
|