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 }