Files
phishingclub/backend/vendor/github.com/enetx/g/map.go
T

227 lines
5.0 KiB
Go

package g
import (
"fmt"
"maps"
"reflect"
)
// Map is a generic alias for a map.
type Map[K comparable, V any] map[K]V
// NewMap creates a new Map of the specified size or an empty Map if no size is provided.
func NewMap[K comparable, V any](size ...Int) Map[K, V] {
if len(size) > 0 {
return make(Map[K, V], size[0])
}
return make(Map[K, V])
}
// Transform applies a transformation function to the Map and returns the result.
func (m Map[K, V]) Transform[U any](fn func(Map[K, V]) U) U { return fn(m) }
// Entry returns an Entry for the given key.
func (m Map[K, V]) Entry(key K) Entry[K, V] {
if _, ok := m[key]; ok {
return OccupiedEntry[K, V]{m: m, key: key}
}
return VacantEntry[K, V]{m: m, key: key}
}
// Iter returns an iterator (Seq2[K, V]) for the Map, allowing for sequential iteration
// over its key-value pairs. It is commonly used in combination with higher-order functions,
// such as 'ForEach', to perform operations on each key-value pair of the Map.
//
// Returns:
//
// - Seq2[K, V], which can be used for sequential iteration over the key-value pairs of the Map.
//
// Example usage:
//
// myMap := g.Map[string, int]{"one": 1, "two": 2, "three": 3}
// iterator := myMap.Iter()
// iterator.ForEach(func(key string, value int) {
// // Perform some operation on each key-value pair
// fmt.Printf("%s: %d\n", key, value)
// })
//
// The 'Iter' method provides a convenient way to traverse the key-value pairs of a Map
// in a functional style, enabling operations like mapping or filtering.
func (m Map[K, V]) Iter() Seq2[K, V] {
return func(yield func(K, V) bool) {
for k, v := range m {
if !yield(k, v) {
return
}
}
}
}
// Keys returns a slice of the Map's keys.
func (m Map[K, V]) Keys() Slice[K] {
if m.IsEmpty() {
return NewSlice[K]()
}
keys := make(Slice[K], 0, len(m))
for k := range m {
keys = append(keys, k)
}
return keys
}
// Values returns a slice of the Map's values.
func (m Map[K, V]) Values() Slice[V] {
if m.IsEmpty() {
return NewSlice[V]()
}
values := make(Slice[V], 0, len(m))
for _, v := range m {
values = append(values, v)
}
return values
}
// Contains checks if the Map contains the specified key.
func (m Map[K, V]) Contains(key K) bool {
_, ok := m[key]
return ok
}
// Clone creates a new Map that is a copy of the original Map.
func (m Map[K, V]) Clone() Map[K, V] { return maps.Clone(m) }
// Copy copies the source Map's key-value pairs to the target Map.
func (m Map[K, V]) Copy(src Map[K, V]) { maps.Copy(m, src) }
// Remove removes the specified key from the Map and returns the removed value.
func (m Map[K, V]) Remove(key K) Option[V] {
if v, ok := m[key]; ok {
delete(m, key)
return Some(v)
}
return None[V]()
}
// Std converts the Map to a regular Go map.
func (m Map[K, V]) Std() map[K]V { return m }
// Eq checks if two Maps are equal.
func (m Map[K, V]) Eq(other Map[K, V]) bool {
n := len(m)
if n != len(other) {
return false
}
if n == 0 {
return true
}
comparable := isValueComparable[V]()
for k, value := range m {
ovalue, ok := other[k]
if !ok {
return false
}
if comparable {
if any(value) != any(ovalue) {
return false
}
} else {
if !reflect.DeepEqual(value, ovalue) {
return false
}
}
}
return true
}
// String returns a string representation of the Map.
func (m Map[K, V]) String() string {
if len(m) == 0 {
return "Map{}"
}
var b Builder
b.Grow(Int(len(m)) * 16)
b.WriteString("Map{")
first := true
for k, v := range m {
if !first {
b.WriteString(", ")
}
first = false
fmt.Fprint(&b, k)
b.WriteByte(':')
fmt.Fprint(&b, v)
}
b.WriteString("}")
return b.String().Std()
}
// Clear removes all key-value pairs from the Map.
func (m Map[K, V]) Clear() { clear(m) }
// IsEmpty checks if the Map is empty.
func (m Map[K, V]) IsEmpty() bool { return len(m) == 0 }
// Get retrieves the value associated with the given key.
func (m Map[K, V]) Get(k K) Option[V] {
if v, ok := m[k]; ok {
return Some(v)
}
return None[V]()
}
// Len returns the number of key-value pairs in the Map.
func (m Map[K, V]) Len() Int { return Int(len(m)) }
// Ne checks if two Maps are not equal.
func (m Map[K, V]) Ne(other Map[K, V]) bool { return !m.Eq(other) }
// Insert sets the value for the key and returns the previous value if it existed.
func (m Map[K, V]) Insert(key K, value V) Option[V] {
prev, ok := m[key]
m[key] = value
if ok {
return Some(prev)
}
return None[V]()
}
// Print writes the key-value pairs of the Map to the standard output (console)
// and returns the Map unchanged.
func (m Map[K, V]) Print() Map[K, V] { fmt.Print(m); return m }
// Println writes the key-value pairs of the Map to the standard output (console) with a newline
// and returns the Map unchanged.
func (m Map[K, V]) Println() Map[K, V] { fmt.Println(m); return m }
// MapOf creates a Map from the provided key-value pairs.
//
// Example:
//
// m := g.MapOf(g.PairOf("a", 1), g.PairOf("b", 2))
func MapOf[K comparable, V any](pairs ...Pair[K, V]) Map[K, V] {
m := NewMap[K, V](Int(len(pairs)))
for _, p := range pairs {
m[p.Key] = p.Value
}
return m
}