mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-10-04 14:36:50 +02:00
227 lines
5.0 KiB
Go
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
|
|
}
|