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

     1  package g
     2  
     3  import (
     4  	"fmt"
     5  	"slices"
     6  
     7  	"github.com/enetx/g/cmp"
     8  	"github.com/enetx/g/f"
     9  )
    10  
    11  // NewMapOrd creates a new ordered Map with the specified size (if provided).
    12  // An ordered Map is an Map that maintains the order of its key-value pairs based on the
    13  // insertion order. If no size is provided, the default size will be used.
    14  //
    15  // Parameters:
    16  //
    17  // - size ...int: (Optional) The initial size of the ordered Map. If not provided, a default size
    18  // will be used.
    19  //
    20  // Returns:
    21  //
    22  // - MapOrd[K, V]: Ordered Map with the specified initial size (or default
    23  // size if not provided).
    24  //
    25  // Example usage:
    26  //
    27  //	mapOrd := g.NewMapOrd[string, int](10)
    28  //
    29  // Creates a new ordered Map with an initial size of 10.
    30  func NewMapOrd[K, V any](size ...Int) MapOrd[K, V] {
    31  	if len(size) == 0 {
    32  		return make(MapOrd[K, V], 0)
    33  	}
    34  
    35  	return make(MapOrd[K, V], 0, size[0])
    36  }
    37  
    38  // Iter returns an iterator (SeqMapOrd[K, V]) for the ordered Map, allowing for sequential iteration
    39  // over its key-value pairs. It is commonly used in combination with higher-order functions,
    40  // such as 'ForEach', to perform operations on each key-value pair of the ordered Map.
    41  //
    42  // Returns:
    43  //
    44  // A SeqMapOrd[K, V], which can be used for sequential iteration over the key-value pairs of the ordered Map.
    45  //
    46  // Example usage:
    47  //
    48  //	iter := g.NewMapOrd[int, int]()
    49  //	iter.
    50  //		Set(1, 1).
    51  //		Set(2, 2).
    52  //		Set(3, 3).
    53  //		Iter()
    54  //
    55  //	iter.ForEach(func(k, v int) {
    56  //	    // Process key-value pair
    57  //	})
    58  //
    59  // The 'Iter' method provides a convenient way to traverse the key-value pairs of an ordered Map
    60  // in a functional style, enabling operations like mapping or filtering.
    61  func (mo MapOrd[K, V]) Iter() SeqMapOrd[K, V] { return ToSeqMapOrd(mo) }
    62  
    63  // MapOrdFromMap converts a standard Map to an ordered Map.
    64  // The resulting ordered Map will maintain the order of its key-value pairs based on the order of
    65  // insertion.
    66  // This function is useful when you want to create an ordered Map from an existing Map.
    67  //
    68  // Parameters:
    69  //
    70  // - m Map[K, V]: The input Map to be converted to an ordered Map.
    71  //
    72  // Returns:
    73  //
    74  // - MapOrd[K, V]: New ordered Map containing the same key-value pairs as the
    75  // input Map.
    76  //
    77  // Example usage:
    78  //
    79  //	mapOrd := g.MapOrdFromMap[string, int](hmap)
    80  //
    81  // Converts the standard Map 'hmap' to an ordered Map.
    82  func MapOrdFromMap[K comparable, V any](m Map[K, V]) MapOrd[K, V] {
    83  	mo := NewMapOrd[K, V](m.Len())
    84  
    85  	for k, v := range m {
    86  		mo.Set(k, v)
    87  	}
    88  
    89  	return mo
    90  }
    91  
    92  // MapOrdFromStd converts a standard Go map to an ordered Map.
    93  // The resulting ordered Map will maintain the order of its key-value pairs based on the order of
    94  // insertion.
    95  // This function is useful when you want to create an ordered Map from an existing Go map.
    96  //
    97  // Parameters:
    98  //
    99  // - m map[K]V: The input Go map to be converted to an ordered Map.
   100  //
   101  // Returns:
   102  //
   103  // - MapOrd[K, V]: New ordered Map containing the same key-value pairs as the
   104  // input Go map.
   105  //
   106  // Example usage:
   107  //
   108  //	mapOrd := g.MapOrdFromStd[string, int](goMap)
   109  //
   110  // Converts the standard Go map 'map[K]V' to an ordered Map.
   111  func MapOrdFromStd[K comparable, V any](m map[K]V) MapOrd[K, V] { return MapOrdFromMap(MapFromStd(m)) }
   112  
   113  // SortBy sorts the ordered Map by a custom comparison function.
   114  //
   115  // Parameters:
   116  //
   117  // - fn func(a, b Pair[K, V]) cmp.Ordering: The custom comparison function used for sorting the ordered Map.
   118  //
   119  // Returns:
   120  //
   121  // - MapOrd[K, V]: Same ordered Map, sorted according to the custom comparison
   122  // function.
   123  //
   124  // Example usage:
   125  //
   126  //	hmapo.SortBy(func(a, b g.Pair[g.String, g.Int]) cmp.Ordering { return a.Key.Cmp(b.Key) })
   127  //	hmapo.SortBy(func(a, b g.Pair[g.String, g.Int]) cmp.Ordering { return a.Value.Cmp(b.Value) })
   128  func (mo MapOrd[K, V]) SortBy(fn func(a, b Pair[K, V]) cmp.Ordering) MapOrd[K, V] {
   129  	slices.SortFunc(mo, func(a, b Pair[K, V]) int { return int(fn(a, b)) })
   130  	return mo
   131  }
   132  
   133  // SortByKey sorts the ordered MapOrd[K, V] by the keys using a custom comparison function.
   134  //
   135  // Parameters:
   136  //
   137  // - fn func(a, b K) cmp.Ordering: The custom comparison function used for sorting the keys.
   138  //
   139  // Returns:
   140  //
   141  // - MapOrd[K, V]: The same ordered MapOrd, sorted by the keys according to the custom comparison function.
   142  //
   143  // Example usage:
   144  //
   145  //	hmapo.SortByKey(func(a, b g.String) cmp.Ordering { return a.Cmp(b) })
   146  func (mo MapOrd[K, V]) SortByKey(fn func(a, b K) cmp.Ordering) MapOrd[K, V] {
   147  	slices.SortFunc(mo, func(a, b Pair[K, V]) int { return int(fn(a.Key, b.Key)) })
   148  	return mo
   149  }
   150  
   151  // SortByValue sorts the ordered MapOrd[K, V] by the values using a custom comparison function.
   152  //
   153  // Parameters:
   154  //
   155  // - fn func(a, b V) cmp.Ordering: The custom comparison function used for sorting the values.
   156  //
   157  // Returns:
   158  //
   159  // - MapOrd[K, V]: The same ordered MapOrd, sorted by the values according to the custom comparison function.
   160  //
   161  // Example usage:
   162  //
   163  //	hmapo.SortByValue(func(a, b g.Int) cmp.Ordering { return a.Cmp(b) })
   164  func (mo MapOrd[K, V]) SortByValue(fn func(a, b V) cmp.Ordering) MapOrd[K, V] {
   165  	slices.SortFunc(mo, func(a, b Pair[K, V]) int { return int(fn(a.Value, b.Value)) })
   166  	return mo
   167  }
   168  
   169  // Clone creates a new ordered Map with the same key-value pairs.
   170  func (mo MapOrd[K, V]) Clone() MapOrd[K, V] {
   171  	result := NewMapOrd[K, V](mo.Len())
   172  	mo.Iter().ForEach(func(k K, v V) { result.Set(k, v) })
   173  
   174  	return result
   175  }
   176  
   177  // Copy copies key-value pairs from the source ordered Map to the current ordered Map.
   178  func (mo *MapOrd[K, V]) Copy(src MapOrd[K, V]) MapOrd[K, V] {
   179  	src.Iter().ForEach(func(k K, v V) { mo.Set(k, v) })
   180  	return *mo
   181  }
   182  
   183  // ToMap converts the ordered Map to a standard Map.
   184  // func (mo MapOrd[K, V]) ToMap() Map[K, V] {
   185  // 	m := NewMap[K, V](len(mo))
   186  // 	mo.Iter().ForEach(func(k K, v V) { m.Set(k, v) })
   187  
   188  // 	return m
   189  // }
   190  
   191  // Set sets the value for the specified key in the ordered Map.
   192  func (mo *MapOrd[K, V]) Set(key K, value V) *MapOrd[K, V] {
   193  	if i := mo.index(key); i != -1 {
   194  		(*mo)[i].Value = value
   195  		return mo
   196  	}
   197  
   198  	mp := Pair[K, V]{key, value}
   199  	*mo = append(*mo, mp)
   200  
   201  	return mo
   202  }
   203  
   204  // Get retrieves the value for the specified key, along with a boolean indicating whether the key
   205  // was found in the ordered Map. This function is useful when you want to access the value
   206  // associated with a key in the ordered Map, and also check if the key exists in the map.
   207  //
   208  // Parameters:
   209  //
   210  // - key K: The key to search for in the ordered Map.
   211  //
   212  // Returns:
   213  //
   214  // - V: The value associated with the specified key if found, or the zero value for the value type
   215  // if the key is not found.
   216  //
   217  // - bool: A boolean value indicating whether the key was found in the ordered Map.
   218  //
   219  // Example usage:
   220  //
   221  //	value, found := mo.Get("some_key")
   222  //
   223  // Retrieves the value associated with the key "some_key" and checks if the key exists in the
   224  // ordered Map.
   225  func (mo MapOrd[K, V]) Get(key K) Option[V] {
   226  	if i := mo.index(key); i != -1 {
   227  		return Some(mo[i].Value)
   228  	}
   229  
   230  	return None[V]()
   231  }
   232  
   233  // GetOrSet returns the value for a key. If the key does not exist, it returns the default value
   234  // instead and also sets the default value for the key in the ordered Map. This function is useful
   235  // when you want to access the value associated with a key in the ordered Map, and if the key does
   236  // not exist, you want to return a specified default value and set that default value for the key.
   237  //
   238  // Parameters:
   239  //
   240  // - key K: The key to search for in the ordered Map.
   241  //
   242  // - defaultValue V: The default value to return if the key is not found in the ordered Map.
   243  // If the key is not found, this default value will also be set for the key in the ordered Map.
   244  //
   245  // Returns:
   246  //
   247  // - V: The value associated with the specified key if found, or the provided default value if the key is not found.
   248  //
   249  // Example usage:
   250  //
   251  //	value := mo.GetOrSet("some_key", "default_value")
   252  //
   253  // Retrieves the value associated with the key "some_key" or returns "default_value" if the key is
   254  // not found, and sets "default_value" as the value for "some_key" in the ordered Map if it's not
   255  // present.
   256  func (mo *MapOrd[K, V]) GetOrSet(key K, defaultValue V) V {
   257  	if value := mo.Get(key); value.IsSome() {
   258  		return value.Some()
   259  	}
   260  
   261  	mo.Set(key, defaultValue)
   262  
   263  	return defaultValue
   264  }
   265  
   266  // Invert inverts the key-value pairs in the ordered Map, creating a new ordered Map with the
   267  // values as keys and the original keys as values.
   268  func (mo MapOrd[K, V]) Invert() MapOrd[V, K] {
   269  	result := NewMapOrd[V, K](mo.Len())
   270  	mo.Iter().ForEach(func(k K, v V) { result.Set(v, k) })
   271  
   272  	return result
   273  }
   274  
   275  func (mo MapOrd[K, V]) index(key K) int {
   276  	if f.Comparable(key) {
   277  		for i, mp := range mo {
   278  			if f.Eq[any](mp.Key)(key) {
   279  				return i
   280  			}
   281  		}
   282  
   283  		return -1
   284  	}
   285  
   286  	for i, mp := range mo {
   287  		if f.Eqd(mp.Key)(key) {
   288  			return i
   289  		}
   290  	}
   291  
   292  	return -1
   293  }
   294  
   295  // Keys returns an Slice containing all the keys in the ordered Map.
   296  func (mo MapOrd[K, V]) Keys() Slice[K] { return mo.Iter().Keys().Collect() }
   297  
   298  // Values returns an Slice containing all the values in the ordered Map.
   299  func (mo MapOrd[K, V]) Values() Slice[V] { return mo.Iter().Values().Collect() }
   300  
   301  // Delete removes the specified keys from the ordered Map.
   302  func (mo *MapOrd[K, V]) Delete(keys ...K) MapOrd[K, V] {
   303  	for _, key := range keys {
   304  		if i := mo.index(key); i != -1 {
   305  			*mo = append((*mo)[:i], (*mo)[i+1:]...)
   306  		}
   307  	}
   308  
   309  	return *mo
   310  }
   311  
   312  // Eq compares the current ordered Map to another ordered Map and returns true if they are equal.
   313  func (mo MapOrd[K, V]) Eq(other MapOrd[K, V]) bool {
   314  	if len(mo) != len(other) || mo.Empty() {
   315  		return false
   316  	}
   317  
   318  	comparable := f.Comparable(mo[0].Value)
   319  
   320  	for _, mp := range mo {
   321  		value := other.Get(mp.Key)
   322  		if value.IsNone() || (comparable && !f.Eq[any](value.Some())(mp.Value)) ||
   323  			(!comparable && !f.Eqd(value.Some())(mp.Value)) {
   324  			return false
   325  		}
   326  	}
   327  
   328  	return true
   329  }
   330  
   331  // String returns a string representation of the ordered Map.
   332  func (mo MapOrd[K, V]) String() string {
   333  	builder := NewBuilder()
   334  
   335  	mo.Iter().ForEach(func(k K, v V) { builder.Write(Sprintf("%v:%v, ", k, v)) })
   336  
   337  	return builder.String().TrimRight(", ").Format("MapOrd{%s}").Std()
   338  }
   339  
   340  // Clear removes all key-value pairs from the ordered Map.
   341  func (mo *MapOrd[K, V]) Clear() MapOrd[K, V] { return mo.Delete(mo.Keys()...) }
   342  
   343  // Contains checks if the ordered Map contains the specified key.
   344  func (mo MapOrd[K, V]) Contains(key K) bool { return mo.index(key) >= 0 }
   345  
   346  // Empty checks if the ordered Map is empty.
   347  func (mo MapOrd[K, V]) Empty() bool { return len(mo) == 0 }
   348  
   349  // Len returns the number of key-value pairs in the ordered Map.
   350  func (mo MapOrd[K, V]) Len() Int { return Int(len(mo)) }
   351  
   352  // Ne compares the current ordered Map to another ordered Map and returns true if they are not
   353  // equal.
   354  func (mo MapOrd[K, V]) Ne(other MapOrd[K, V]) bool { return !mo.Eq(other) }
   355  
   356  // NotEmpty checks if the ordered Map is not empty.
   357  func (mo MapOrd[K, V]) NotEmpty() bool { return !mo.Empty() }
   358  
   359  // Print prints the key-value pairs of the MapOrd to the standard output (console)
   360  // and returns the MapOrd pointer unchanged.
   361  func (mo MapOrd[K, V]) Print() MapOrd[K, V] { fmt.Println(mo); return mo }