Initial QSfera import
This commit is contained in:
+245
@@ -0,0 +1,245 @@
|
||||
package tw
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// KeyValuePair represents a single key-value pair from a Mapper.
|
||||
type KeyValuePair[K comparable, V any] struct {
|
||||
Key K
|
||||
Value V
|
||||
}
|
||||
|
||||
// Mapper is a generic map type with comparable keys and any value type.
|
||||
// It provides type-safe operations on maps with additional convenience methods.
|
||||
type Mapper[K comparable, V any] map[K]V
|
||||
|
||||
// NewMapper creates and returns a new initialized Mapper.
|
||||
func NewMapper[K comparable, V any]() Mapper[K, V] {
|
||||
return make(Mapper[K, V])
|
||||
}
|
||||
|
||||
// Get returns the value associated with the key.
|
||||
// If the key doesn't exist or the map is nil, it returns the zero value for the value type.
|
||||
func (m Mapper[K, V]) Get(key K) V {
|
||||
if m == nil {
|
||||
var zero V
|
||||
return zero
|
||||
}
|
||||
return m[key]
|
||||
}
|
||||
|
||||
// OK returns the value associated with the key and a boolean indicating whether the key exists.
|
||||
func (m Mapper[K, V]) OK(key K) (V, bool) {
|
||||
if m == nil {
|
||||
var zero V
|
||||
return zero, false
|
||||
}
|
||||
val, ok := m[key]
|
||||
return val, ok
|
||||
}
|
||||
|
||||
// Set sets the value for the specified key.
|
||||
// Does nothing if the map is nil.
|
||||
func (m Mapper[K, V]) Set(key K, value V) Mapper[K, V] {
|
||||
if m != nil {
|
||||
m[key] = value
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// Delete removes the specified key from the map.
|
||||
// Does nothing if the key doesn't exist or the map is nil.
|
||||
func (m Mapper[K, V]) Delete(key K) Mapper[K, V] {
|
||||
if m != nil {
|
||||
delete(m, key)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// Has returns true if the key exists in the map, false otherwise.
|
||||
func (m Mapper[K, V]) Has(key K) bool {
|
||||
if m == nil {
|
||||
return false
|
||||
}
|
||||
_, exists := m[key]
|
||||
return exists
|
||||
}
|
||||
|
||||
// Len returns the number of elements in the map.
|
||||
// Returns 0 if the map is nil.
|
||||
func (m Mapper[K, V]) Len() int {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
return len(m)
|
||||
}
|
||||
|
||||
// Keys returns a slice containing all keys in the map.
|
||||
// Returns nil if the map is nil or empty.
|
||||
func (m Mapper[K, V]) Keys() []K {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
keys := make([]K, 0, len(m))
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
func (m Mapper[K, V]) Clear() {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
for k := range m {
|
||||
delete(m, k)
|
||||
}
|
||||
}
|
||||
|
||||
// Values returns a slice containing all values in the map.
|
||||
// Returns nil if the map is nil or empty.
|
||||
func (m Mapper[K, V]) Values() []V {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
values := make([]V, 0, len(m))
|
||||
for _, v := range m {
|
||||
values = append(values, v)
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
// Each iterates over each key-value pair in the map and calls the provided function.
|
||||
// Does nothing if the map is nil.
|
||||
func (m Mapper[K, V]) Each(fn func(K, V)) {
|
||||
for k, v := range m {
|
||||
fn(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// Filter returns a new Mapper containing only the key-value pairs that satisfy the predicate.
|
||||
func (m Mapper[K, V]) Filter(fn func(K, V) bool) Mapper[K, V] {
|
||||
result := NewMapper[K, V]()
|
||||
for k, v := range m {
|
||||
if fn(k, v) {
|
||||
result[k] = v
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// MapValues returns a new Mapper with the same keys but values transformed by the provided function.
|
||||
func (m Mapper[K, V]) MapValues(fn func(V) V) Mapper[K, V] {
|
||||
result := NewMapper[K, V]()
|
||||
for k, v := range m {
|
||||
result[k] = fn(v)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Clone returns a shallow copy of the Mapper.
|
||||
func (m Mapper[K, V]) Clone() Mapper[K, V] {
|
||||
result := NewMapper[K, V]()
|
||||
for k, v := range m {
|
||||
result[k] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Slicer converts the Mapper to a Slicer of key-value pairs.
|
||||
func (m Mapper[K, V]) Slicer() Slicer[KeyValuePair[K, V]] {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
result := make(Slicer[KeyValuePair[K, V]], 0, len(m))
|
||||
for k, v := range m {
|
||||
result = append(result, KeyValuePair[K, V]{Key: k, Value: v})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (m Mapper[K, V]) SortedKeys() []K {
|
||||
keys := make([]K, 0, len(m))
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
sort.Slice(keys, func(i, j int) bool {
|
||||
a, b := any(keys[i]), any(keys[j])
|
||||
|
||||
switch va := a.(type) {
|
||||
case int:
|
||||
if vb, ok := b.(int); ok {
|
||||
return va < vb
|
||||
}
|
||||
case int32:
|
||||
if vb, ok := b.(int32); ok {
|
||||
return va < vb
|
||||
}
|
||||
case int64:
|
||||
if vb, ok := b.(int64); ok {
|
||||
return va < vb
|
||||
}
|
||||
case uint:
|
||||
if vb, ok := b.(uint); ok {
|
||||
return va < vb
|
||||
}
|
||||
case uint64:
|
||||
if vb, ok := b.(uint64); ok {
|
||||
return va < vb
|
||||
}
|
||||
case float32:
|
||||
if vb, ok := b.(float32); ok {
|
||||
return va < vb
|
||||
}
|
||||
case float64:
|
||||
if vb, ok := b.(float64); ok {
|
||||
return va < vb
|
||||
}
|
||||
case string:
|
||||
if vb, ok := b.(string); ok {
|
||||
return va < vb
|
||||
}
|
||||
}
|
||||
|
||||
// fallback to string comparison
|
||||
return fmt.Sprintf("%v", a) < fmt.Sprintf("%v", b)
|
||||
})
|
||||
|
||||
return keys
|
||||
}
|
||||
|
||||
func NewBoolMapper[K comparable](keys ...K) Mapper[K, bool] {
|
||||
if len(keys) == 0 {
|
||||
return nil
|
||||
}
|
||||
mapper := NewMapper[K, bool]()
|
||||
for _, key := range keys {
|
||||
mapper.Set(key, true)
|
||||
}
|
||||
return mapper
|
||||
}
|
||||
|
||||
func NewIntMapper[K comparable](keys ...K) Mapper[K, int] {
|
||||
if len(keys) == 0 {
|
||||
return nil
|
||||
}
|
||||
mapper := NewMapper[K, int]()
|
||||
for _, key := range keys {
|
||||
mapper.Set(key, 0)
|
||||
}
|
||||
return mapper
|
||||
}
|
||||
|
||||
func NewIdentityMapper[K comparable](keys ...K) Mapper[K, K] {
|
||||
if len(keys) == 0 {
|
||||
return nil
|
||||
}
|
||||
mapper := NewMapper[K, K]()
|
||||
for _, key := range keys {
|
||||
mapper.Set(key, key)
|
||||
}
|
||||
return mapper
|
||||
}
|
||||
Reference in New Issue
Block a user