github.com/m4gshm/gollections@v0.0.13-0.20240331203319-a34a86e58a24/collection/mutable/map.go (about)

     1  package mutable
     2  
     3  import (
     4  	"fmt"
     5  
     6  	breakLoop "github.com/m4gshm/gollections/break/kv/loop"
     7  	breakMapFilter "github.com/m4gshm/gollections/break/kv/predicate"
     8  	breakMapConvert "github.com/m4gshm/gollections/break/map_/convert"
     9  	"github.com/m4gshm/gollections/c"
    10  	"github.com/m4gshm/gollections/collection"
    11  	"github.com/m4gshm/gollections/collection/immutable"
    12  	"github.com/m4gshm/gollections/collection/mutable/ordered"
    13  	"github.com/m4gshm/gollections/kv/convert"
    14  	"github.com/m4gshm/gollections/kv/loop"
    15  	filter "github.com/m4gshm/gollections/kv/predicate"
    16  	"github.com/m4gshm/gollections/map_"
    17  	"github.com/m4gshm/gollections/slice"
    18  )
    19  
    20  // WrapMap instantiates Map using a map as internal storage.
    21  func WrapMap[K comparable, V any](elements map[K]V) *Map[K, V] {
    22  	m := Map[K, V](elements)
    23  	return &m
    24  }
    25  
    26  // Map is a collection implementation that provides elements access by an unique key.
    27  type Map[K comparable, V any] map[K]V
    28  
    29  var (
    30  	_ c.Deleteable[int]                                                    = (*Map[int, any])(nil)
    31  	_ c.Removable[int, any]                                                = (*Map[int, any])(nil)
    32  	_ c.Settable[int, any]                                                 = (*Map[int, any])(nil)
    33  	_ c.SettableNew[int, any]                                              = (*Map[int, any])(nil)
    34  	_ c.SettableMap[c.TrackEach[int, any]]                                 = (*Map[int, any])(nil)
    35  	_ c.ImmutableMapConvert[immutable.Map[int, any]]                       = (*Map[int, any])(nil)
    36  	_ collection.Map[int, any]                                             = (*Map[int, any])(nil)
    37  	_ c.KeyVal[immutable.MapKeys[int, any], immutable.MapValues[int, any]] = (*Map[int, any])(nil)
    38  	_ fmt.Stringer                                                         = (*Map[int, any])(nil)
    39  )
    40  
    41  // All is used to iterate through the collection using `for ... range`. Supported since go 1.22 with GOEXPERIMENT=rangefunc enabled.
    42  func (m *Map[K, V]) All(consumer func(K, V) bool) {
    43  	if m != nil {
    44  		map_.TrackWhile(*m, consumer)
    45  	}
    46  }
    47  
    48  // Loop creates a loop to iterate through the collection.
    49  func (m *Map[K, V]) Loop() loop.Loop[K, V] {
    50  	h := m.Head()
    51  	return h.Next
    52  }
    53  
    54  // Deprecated: Head is deprecated. Will be replaced by rance-over function iterator.
    55  // Head creates an iterator to iterate through the collection.
    56  func (m *Map[K, V]) Head() map_.Iter[K, V] {
    57  	var out map[K]V
    58  	if m != nil {
    59  		out = *m
    60  	}
    61  	return map_.NewIter(out)
    62  }
    63  
    64  // First returns the first key/value pair of the map, an iterator to iterate over the remaining pair, and true\false marker of availability next pairs.
    65  // Deprecated: First is deprecated. Will be replaced by rance-over function iterator.
    66  // If no more then ok==false.
    67  func (m *Map[K, V]) First() (map_.Iter[K, V], K, V, bool) {
    68  	var out map[K]V
    69  	if m != nil {
    70  		out = *m
    71  	}
    72  	var (
    73  		iterator           = map_.NewIter(out)
    74  		firstK, firstV, ok = iterator.Next()
    75  	)
    76  	return iterator, firstK, firstV, ok
    77  }
    78  
    79  // Map collects the key/value pairs to a map
    80  func (m *Map[K, V]) Map() (out map[K]V) {
    81  	if m == nil {
    82  		return
    83  	}
    84  	return map_.Clone(*m)
    85  }
    86  
    87  // Sort sorts keys in-place (no copy)
    88  func (m *Map[K, V]) Sort(comparer slice.Comparer[K]) *ordered.Map[K, V] {
    89  	return m.sortBy(slice.Sort, comparer)
    90  }
    91  
    92  // StableSort sorts keys in-place (no copy)
    93  func (m *Map[K, V]) StableSort(comparer slice.Comparer[K]) *ordered.Map[K, V] {
    94  	return m.sortBy(slice.StableSort, comparer)
    95  }
    96  
    97  func (m *Map[K, V]) sortBy(sorter func([]K, slice.Comparer[K]) []K, comparer slice.Comparer[K]) *ordered.Map[K, V] {
    98  	if m != nil {
    99  		return ordered.NewMapOf(sorter(m.Keys().Slice(), comparer), m.Map())
   100  	}
   101  	return nil
   102  }
   103  
   104  // Len returns amount of elements
   105  func (m *Map[K, V]) Len() int {
   106  	if m == nil {
   107  		return 0
   108  	}
   109  	return len(*m)
   110  }
   111  
   112  // IsEmpty returns true if the map is empty
   113  func (m *Map[K, V]) IsEmpty() bool {
   114  	return m.Len() == 0
   115  }
   116  
   117  // Track applies the 'consumer' function for all key/value pairs until the consumer returns the c.Break to stop.
   118  func (m *Map[K, V]) Track(consumer func(K, V) error) error {
   119  	if m == nil {
   120  		return nil
   121  	}
   122  	return map_.Track(*m, consumer)
   123  }
   124  
   125  // TrackEach applies the 'consumer' function for every key/value pairs
   126  func (m *Map[K, V]) TrackEach(consumer func(K, V)) {
   127  	if m != nil {
   128  		map_.TrackEach(*m, consumer)
   129  	}
   130  }
   131  
   132  // Contains checks is the map contains a key
   133  func (m *Map[K, V]) Contains(key K) (ok bool) {
   134  	if m != nil {
   135  		_, ok = (*m)[key]
   136  	}
   137  	return ok
   138  }
   139  
   140  // Get returns the value for a key.
   141  // If ok==false, then the map does not contain the key.
   142  func (m *Map[K, V]) Get(key K) (val V, ok bool) {
   143  	if m != nil {
   144  		val, ok = (*m)[key]
   145  	}
   146  	return val, ok
   147  }
   148  
   149  // Set sets the value for a key
   150  func (m *Map[K, V]) Set(key K, value V) {
   151  	if m == nil {
   152  		return
   153  	} else if (*m) == nil {
   154  		*m = Map[K, V]{}
   155  	}
   156  	(*m)[key] = value
   157  }
   158  
   159  // SetNew sets the value fo a key only if the key is not exists in the map
   160  func (m *Map[K, V]) SetNew(key K, value V) bool {
   161  	if m == nil {
   162  		return false
   163  	} else if (*m) == nil {
   164  		*m = Map[K, V]{}
   165  	}
   166  
   167  	if _, ok := (*m)[key]; !ok {
   168  		(*m)[key] = value
   169  		return true
   170  	}
   171  	return false
   172  }
   173  
   174  // Delete removes value by their keys from the map
   175  func (m *Map[K, V]) Delete(keys ...K) {
   176  	for _, key := range keys {
   177  		m.DeleteOne(key)
   178  	}
   179  }
   180  
   181  // DeleteOne removes an value by the key from the map
   182  func (m *Map[K, V]) DeleteOne(key K) {
   183  	if m != nil {
   184  		delete(*m, key)
   185  	}
   186  }
   187  
   188  // Remove removes value by key and return it
   189  func (m *Map[K, V]) Remove(key K) (v V, ok bool) {
   190  	if m == nil {
   191  		return v, ok
   192  	}
   193  	v, ok = m.Get(key)
   194  	m.Delete(key)
   195  	return v, ok
   196  }
   197  
   198  // Keys resutrns keys collection
   199  func (m *Map[K, V]) Keys() immutable.MapKeys[K, V] {
   200  	var elements map[K]V
   201  	if m != nil {
   202  		elements = *m
   203  	}
   204  	return immutable.WrapKeys(elements)
   205  }
   206  
   207  // Values resutrns values collection
   208  func (m *Map[K, V]) Values() immutable.MapValues[K, V] {
   209  	var out map[K]V
   210  	if m != nil {
   211  		out = *m
   212  	}
   213  	return immutable.WrapVal(out)
   214  }
   215  
   216  // String string representation on the map
   217  func (m *Map[K, V]) String() string {
   218  	var out map[K]V
   219  	if m != nil {
   220  		out = *m
   221  	}
   222  	return map_.ToString(out)
   223  }
   224  
   225  // FilterKey returns a loop consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
   226  func (m *Map[K, V]) FilterKey(predicate func(K) bool) loop.Loop[K, V] {
   227  	return loop.Filter(m.Loop(), filter.Key[V](predicate))
   228  }
   229  
   230  // FiltKey returns a breakable loop consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
   231  func (m Map[K, V]) FiltKey(predicate func(K) (bool, error)) breakLoop.Loop[K, V] {
   232  	return loop.Filt(m.Loop(), breakMapFilter.Key[V](predicate))
   233  }
   234  
   235  // ConvertKey returns a loop that applies the 'converter' function to keys of the map
   236  func (m *Map[K, V]) ConvertKey(converter func(K) K) loop.Loop[K, V] {
   237  	return loop.Convert(m.Loop(), convert.Key[V](converter))
   238  }
   239  
   240  // ConvKey returns a breabkable stream that applies the 'converter' function to keys of the map
   241  func (m Map[K, V]) ConvKey(converter func(K) (K, error)) breakLoop.Loop[K, V] {
   242  	return loop.Conv(m.Loop(), breakMapConvert.Key[V](converter))
   243  }
   244  
   245  // FilterValue returns a loop consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
   246  func (m *Map[K, V]) FilterValue(predicate func(V) bool) loop.Loop[K, V] {
   247  	return loop.Filter(m.Loop(), filter.Value[K](predicate))
   248  }
   249  
   250  // FiltValue returns a breakable loop consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
   251  func (m *Map[K, V]) FiltValue(predicate func(V) (bool, error)) breakLoop.Loop[K, V] {
   252  	return loop.Filt(m.Loop(), breakMapFilter.Value[K](predicate))
   253  }
   254  
   255  // ConvertValue returns a loop that applies the 'converter' function to values of the map
   256  func (m *Map[K, V]) ConvertValue(converter func(V) V) loop.Loop[K, V] {
   257  	return loop.Convert(m.Loop(), convert.Value[K](converter))
   258  }
   259  
   260  // ConvValue returns a breakable loop that applies the 'converter' function to values of the map
   261  func (m Map[K, V]) ConvValue(converter func(V) (V, error)) breakLoop.Loop[K, V] {
   262  	return loop.Conv(m.Loop(), breakMapConvert.Value[K](converter))
   263  }
   264  
   265  // Filter returns a loop consisting of elements that satisfy the condition of the 'predicate' function
   266  func (m *Map[K, V]) Filter(predicate func(K, V) bool) loop.Loop[K, V] {
   267  	return loop.Filter(m.Loop(), predicate)
   268  }
   269  
   270  // Filt returns a breakable loop consisting of elements that satisfy the condition of the 'predicate' function
   271  func (m *Map[K, V]) Filt(predicate func(K, V) (bool, error)) breakLoop.Loop[K, V] {
   272  	return loop.Filt(m.Loop(), predicate)
   273  }
   274  
   275  // Convert returns a loop that applies the 'converter' function to the collection elements
   276  func (m *Map[K, V]) Convert(converter func(K, V) (K, V)) loop.Loop[K, V] {
   277  	return loop.Convert(m.Loop(), converter)
   278  }
   279  
   280  // Conv returns a breakable loop that applies the 'converter' function to the collection elements
   281  func (m *Map[K, V]) Conv(converter func(K, V) (K, V, error)) breakLoop.Loop[K, V] {
   282  	return loop.Conv(m.Loop(), converter)
   283  }
   284  
   285  // Reduce reduces the key/value pairs of the map into an one pair using the 'merge' function
   286  func (m *Map[K, V]) Reduce(merge func(K, K, V, V) (K, V)) (k K, v V) {
   287  	if m != nil {
   288  		k, v = map_.Reduce(*m, merge)
   289  	}
   290  	return k, v
   291  }
   292  
   293  // HasAny finds the first key/value pair that satisfies the 'predicate' function condition and returns true if successful
   294  func (m *Map[K, V]) HasAny(predicate func(K, V) bool) bool {
   295  	if m != nil {
   296  		return map_.HasAny(*m, predicate)
   297  	}
   298  	return false
   299  }
   300  
   301  // Immutable converts to an immutable map instance
   302  func (m *Map[K, V]) Immutable() immutable.Map[K, V] {
   303  	return immutable.WrapMap(m.Map())
   304  }
   305  
   306  // SetMap inserts all elements from the 'other' map
   307  func (m *Map[K, V]) SetMap(other c.TrackEach[K, V]) {
   308  	if m == nil || other == nil {
   309  		return
   310  	}
   311  	other.TrackEach(func(key K, value V) { m.Set(key, value) })
   312  }