github.com/m4gshm/gollections@v0.0.10/collection/mutable/map.go (about)

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