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