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