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 }