github.com/enetx/g@v1.0.80/map.go (about)

     1  package g
     2  
     3  import (
     4  	"fmt"
     5  	"maps"
     6  
     7  	"github.com/enetx/g/f"
     8  )
     9  
    10  // NewMap creates a new Map of the specified size or an empty Map if no size is provided.
    11  func NewMap[K comparable, V any](size ...Int) Map[K, V] {
    12  	if len(size) == 0 {
    13  		return make(Map[K, V], 0)
    14  	}
    15  
    16  	return make(Map[K, V], size[0])
    17  }
    18  
    19  // MapFromStd creates an Map from a given Go map.
    20  func MapFromStd[K comparable, V any](stdmap map[K]V) Map[K, V] { return stdmap }
    21  
    22  // Iter returns an iterator (SeqMap[K, V]) for the Map, allowing for sequential iteration
    23  // over its key-value pairs. It is commonly used in combination with higher-order functions,
    24  // such as 'ForEach', to perform operations on each key-value pair of the Map.
    25  //
    26  // Returns:
    27  //
    28  // - SeqMap[K, V], which can be used for sequential iteration over the key-value pairs of the Map.
    29  //
    30  // Example usage:
    31  //
    32  //	myMap := g.Map[string, int]{"one": 1, "two": 2, "three": 3}
    33  //	iterator := myMap.Iter()
    34  //	iterator.ForEach(func(key string, value int) {
    35  //		// Perform some operation on each key-value pair
    36  //		fmt.Printf("%s: %d\n", key, value)
    37  //	})
    38  //
    39  // The 'Iter' method provides a convenient way to traverse the key-value pairs of a Map
    40  // in a functional style, enabling operations like mapping or filtering.
    41  func (m Map[K, V]) Iter() SeqMap[K, V] { return ToSeqMap(m) }
    42  
    43  // Invert inverts the keys and values of the Map, returning a new Map with values as keys and
    44  // keys as values. Note that the inverted Map will have 'any' as the key type, since not all value
    45  // types are guaranteed to be comparable.
    46  func (m Map[K, V]) Invert() Map[any, K] {
    47  	result := NewMap[any, K](m.Len())
    48  	for k, v := range m {
    49  		result.Set(v, k)
    50  	}
    51  
    52  	return result
    53  }
    54  
    55  // Keys returns a slice of the Map's keys.
    56  func (m Map[K, V]) Keys() Slice[K] { return m.Iter().Keys().Collect() }
    57  
    58  // Values returns a slice of the Map's values.
    59  func (m Map[K, V]) Values() Slice[V] { return m.Iter().Values().Collect() }
    60  
    61  // Contains checks if the Map contains the specified key.
    62  func (m Map[K, V]) Contains(key K) bool {
    63  	_, ok := m[key]
    64  	return ok
    65  }
    66  
    67  // Clone creates a new Map that is a copy of the original Map.
    68  func (m Map[K, V]) Clone() Map[K, V] { return maps.Clone(m) }
    69  
    70  // Copy copies the source Map's key-value pairs to the target Map.
    71  func (m Map[K, V]) Copy(src Map[K, V]) Map[K, V] {
    72  	maps.Copy(m, src)
    73  	return m
    74  }
    75  
    76  // Delete removes the specified keys from the Map.
    77  func (m Map[K, V]) Delete(keys ...K) Map[K, V] {
    78  	for _, key := range keys {
    79  		delete(m, key)
    80  	}
    81  
    82  	return m
    83  }
    84  
    85  // Std converts the Map to a regular Go map.
    86  func (m Map[K, V]) Std() map[K]V { return m }
    87  
    88  // Eq checks if two Maps are equal.
    89  func (m Map[K, V]) Eq(other Map[K, V]) bool {
    90  	if len(m) != len(other) || m.Empty() {
    91  		return false
    92  	}
    93  
    94  	key := m.Iter().Take(1).Keys().Collect()[0]
    95  	comparable := f.Comparable(key) && f.Comparable(m[key])
    96  
    97  	for k, v1 := range m {
    98  		v2, ok := other[k]
    99  		if !ok || (comparable && !f.Eq[any](v1)(v2)) || (!comparable && !f.Eqd(v1)(v2)) {
   100  			return false
   101  		}
   102  	}
   103  
   104  	return true
   105  }
   106  
   107  // String returns a string representation of the Map.
   108  func (m Map[K, V]) String() string {
   109  	builder := NewBuilder()
   110  
   111  	for k, v := range m {
   112  		builder.Write(Sprintf("%v:%v, ", k, v))
   113  	}
   114  
   115  	return builder.String().TrimRight(", ").Format("Map{%s}").Std()
   116  }
   117  
   118  // GetOrSet returns the value for a key. If the key exists in the Map, it returns the associated value.
   119  // If the key does not exist, it sets the key to the provided default value and returns that value.
   120  // This function is useful when you want to both retrieve and potentially set a default value for keys
   121  // that may or may not be present in the Map.
   122  //
   123  // Parameters:
   124  //
   125  // - key K: The key for which to retrieve the value.
   126  //
   127  // - defaultValue V: The default value to return if the key does not exist in the Map.
   128  // If the key is not found, this default value will also be set for the key in the Map.
   129  //
   130  // Returns:
   131  //
   132  // - V: The value associated with the key if it exists in the Map, or the default value if the key is not found.
   133  //
   134  // Eaxmple usage:
   135  //
   136  //	// Create a new ordered Map called "gos" with string keys and integer pointers as values
   137  //	gos := g.NewMap[string, *int]()
   138  //
   139  //	// Use GetOrSet to set the value for the key "root" to 3 if it doesn't exist,
   140  //	// and then print whether the value is equal to 3.
   141  //	gos.GetOrSet("root", ref.Of(3))
   142  //	fmt.Println(*gos.Get("root") == 3) // Should print "true"
   143  //
   144  //	// Use GetOrSet to retrieve the value for the key "root" (which is 3), multiply it by 2,
   145  //	// and then print whether the value is equal to 6.
   146  //	*gos.GetOrSet("root", ref.Of(10)) *= 2
   147  //	fmt.Println(*gos.Get("root") == 6) // Should print "true"
   148  //
   149  // In this example, you first create an ordered Map "gos" with string keys and integer pointers as values.
   150  // Then, you use GetOrSet to set and retrieve values for the key "root" with default values of 3 and perform
   151  // multiplication operations, demonstrating the behavior of GetOrSet.
   152  func (m Map[K, V]) GetOrSet(key K, defaultValue V) V {
   153  	if value, ok := m[key]; ok {
   154  		return value
   155  	}
   156  
   157  	m[key] = defaultValue
   158  
   159  	return defaultValue
   160  }
   161  
   162  // Clear removes all key-value pairs from the Map.
   163  func (m Map[K, V]) Clear() Map[K, V] { clear(m); return m }
   164  
   165  // Empty checks if the Map is empty.
   166  func (m Map[K, V]) Empty() bool { return len(m) == 0 }
   167  
   168  // Get retrieves the value associated with the given key.
   169  func (m Map[K, V]) Get(k K) Option[V] {
   170  	if v, ok := m[k]; ok {
   171  		return Some(v)
   172  	}
   173  
   174  	return None[V]()
   175  }
   176  
   177  // Len returns the number of key-value pairs in the Map.
   178  func (m Map[K, V]) Len() Int { return Int(len(m)) }
   179  
   180  // Ne checks if two Maps are not equal.
   181  func (m Map[K, V]) Ne(other Map[K, V]) bool { return !m.Eq(other) }
   182  
   183  // NotEmpty checks if the Map is not empty.
   184  func (m Map[K, V]) NotEmpty() bool { return !m.Empty() }
   185  
   186  // Set sets the value for the given key in the Map.
   187  func (m Map[K, V]) Set(k K, v V) Map[K, V] { m[k] = v; return m }
   188  
   189  // Print prints the key-value pairs of the Map to the standard output (console)
   190  // and returns the Map unchanged.
   191  func (m Map[K, V]) Print() Map[K, V] { fmt.Println(m); return m }