github.com/m4gshm/gollections@v0.0.10/collection/immutable/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 kvstream "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/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 "github.com/m4gshm/gollections/notsafe" 20 "github.com/m4gshm/gollections/slice" 21 ) 22 23 // WrapMap instantiates ordered Map using a map and an order slice as internal storage. 24 func WrapMap[K comparable, V any](order []K, elements map[K]V) Map[K, V] { 25 return Map[K, V]{order: order, elements: elements, ksize: notsafe.GetTypeSize[K]()} 26 } 27 28 // Map is a collection implementation that provides elements access by an unique key. 29 type Map[K comparable, V any] struct { 30 order []K 31 elements map[K]V 32 ksize uintptr 33 } 34 35 var ( 36 _ collection.Map[int, any] = (*Map[int, any])(nil) 37 _ collection.Map[int, any] = Map[int, any]{} 38 _ loop.Looper[int, any, *MapIter[int, any]] = (*Map[int, any])(nil) 39 _ loop.Looper[int, any, *MapIter[int, any]] = Map[int, any]{} 40 _ c.KeyVal[MapKeys[int], MapValues[int, any]] = (*Map[int, any])(nil) 41 _ c.KeyVal[MapKeys[int], MapValues[int, any]] = Map[int, any]{} 42 _ fmt.Stringer = (*Map[int, any])(nil) 43 _ fmt.Stringer = Map[int, any]{} 44 ) 45 46 // Iter creates an iterator and returns as interface 47 func (m Map[K, V]) Iter() kv.Iterator[K, V] { 48 h := m.Head() 49 return &h 50 } 51 52 // Loop creates an iterator and returns as implementation type reference 53 func (m Map[K, V]) Loop() *MapIter[K, V] { 54 h := m.Head() 55 return &h 56 } 57 58 // Head creates an iterator and returns as implementation type value 59 func (m Map[K, V]) Head() MapIter[K, V] { 60 return NewMapIter(m.elements, slice.NewHeadS(m.order, m.ksize)) 61 } 62 63 // 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. 64 // If no more then ok==false. 65 func (m Map[K, V]) First() (MapIter[K, V], K, V, bool) { 66 var ( 67 iterator = m.Head() 68 firstK, firstV, ok = iterator.Next() 69 ) 70 return iterator, firstK, firstV, ok 71 } 72 73 // Tail creates an iterator pointing to the end of the map 74 func (m Map[K, V]) Tail() MapIter[K, V] { 75 return NewMapIter(m.elements, slice.NewTailS(m.order, m.ksize)) 76 } 77 78 // Map collects the key/value pairs to a map 79 func (m Map[K, V]) Map() map[K]V { 80 return map_.Clone(m.elements) 81 } 82 83 // Len returns amount of elements 84 func (m Map[K, V]) Len() int { 85 return len(m.order) 86 } 87 88 // IsEmpty returns true if the map is empty 89 func (m Map[K, V]) IsEmpty() bool { 90 return m.Len() == 0 91 } 92 93 // Contains checks is the map contains a key 94 func (m Map[K, V]) Contains(key K) (ok bool) { 95 if m.elements != nil { 96 _, ok = m.elements[key] 97 } 98 return ok 99 } 100 101 // Get returns the value for a key. 102 // If ok==false, then the map does not contain the key. 103 func (m Map[K, V]) Get(key K) (element V, ok bool) { 104 if m.elements != nil { 105 element, ok = m.elements[key] 106 } 107 return element, ok 108 } 109 110 // Keys resutrns keys collection 111 func (m Map[K, V]) Keys() MapKeys[K] { 112 return WrapKeys(m.order) 113 } 114 115 // Values resutrns values collection 116 func (m Map[K, V]) Values() MapValues[K, V] { 117 return WrapVal(m.order, m.elements) 118 } 119 120 // Sort sorts the elements 121 func (m Map[K, V]) Sort(less slice.Less[K]) Map[K, V] { 122 return m.sortBy(sort.Slice, less) 123 } 124 125 // StableSort sorts the elements 126 func (m Map[K, V]) StableSort(less slice.Less[K]) Map[K, V] { 127 return m.sortBy(sort.SliceStable, less) 128 } 129 130 func (m Map[K, V]) sortBy(sorter slice.Sorter, less slice.Less[K]) Map[K, V] { 131 order := slice.Clone(m.order) 132 slice.Sort(order, sorter, less) 133 return WrapMap(order, m.elements) 134 } 135 136 func (m Map[K, V]) String() string { 137 return map_.ToStringOrdered(m.order, m.elements) 138 } 139 140 // Track applies the 'tracker' function for key/value pairs. Return the c.ErrBreak to stop. 141 func (m Map[K, V]) Track(tracker func(K, V) error) error { 142 return map_.TrackOrdered(m.order, m.elements, tracker) 143 } 144 145 // TrackEach applies the 'tracker' function for every key/value pairs 146 func (m Map[K, V]) TrackEach(tracker func(K, V)) { 147 map_.TrackEachOrdered(m.order, m.elements, tracker) 148 } 149 150 // For applies the 'walker' function for key/value pairs. Return the c.ErrBreak to stop. 151 func (m Map[K, V]) For(walker func(c.KV[K, V]) error) error { 152 return map_.ForOrdered(m.order, m.elements, walker) 153 } 154 155 // ForEach applies the 'walker' function for every key/value pair 156 func (m Map[K, V]) ForEach(walker func(c.KV[K, V])) { 157 map_.ForEachOrdered(m.order, m.elements, walker) 158 } 159 160 // FilterKey returns a stream consisting of key/value pairs where the key satisfies the condition of the 'predicate' function 161 func (m Map[K, V]) FilterKey(predicate func(K) bool) stream.Iter[K, V, map[K]V] { 162 h := m.Head() 163 return stream.New(loop.Filter(h.Next, filter.Key[V](predicate)).Next, loop.ToMap[K, V]) 164 } 165 166 // FiltKey returns a stream consisting of key/value pairs where the key satisfies the condition of the 'predicate' function 167 func (m Map[K, V]) FiltKey(predicate func(K) (bool, error)) kvstream.Iter[K, V, map[K]V] { 168 h := m.Head() 169 return kvstream.New(breakLoop.Filt(breakLoop.From(h.Next), breakMapFilter.Key[V](predicate)).Next, breakLoop.ToMap[K, V]) 170 } 171 172 // ConvertKey returns a stream that applies the 'converter' function to keys of the map 173 func (m Map[K, V]) ConvertKey(by func(K) K) stream.Iter[K, V, map[K]V] { 174 h := m.Head() 175 return stream.New(loop.Convert(h.Next, convert.Key[V](by)).Next, loop.ToMap[K, V]) 176 } 177 178 // ConvKey returns a stream that applies the 'converter' function to keys of the map 179 func (m Map[K, V]) ConvKey(converter func(K) (K, error)) kvstream.Iter[K, V, map[K]V] { 180 h := m.Head() 181 return kvstream.New(breakLoop.Conv(breakLoop.From(h.Next), breakMapConvert.Key[V](converter)).Next, breakLoop.ToMap[K, V]) 182 } 183 184 // FilterValue returns a stream consisting of key/value pairs where the value satisfies the condition of the 'predicate' function 185 func (m Map[K, V]) FilterValue(predicate func(V) bool) stream.Iter[K, V, map[K]V] { 186 h := m.Head() 187 return stream.New(loop.Filter(h.Next, filter.Value[K](predicate)).Next, loop.ToMap[K, V]) 188 } 189 190 // FiltValue returns a breakable stream consisting of key/value pairs where the value satisfies the condition of the 'predicate' function 191 func (m Map[K, V]) FiltValue(predicate func(V) (bool, error)) kvstream.Iter[K, V, map[K]V] { 192 h := m.Head() 193 return kvstream.New(breakLoop.Filt(breakLoop.From(h.Next), breakMapFilter.Value[K](predicate)).Next, breakLoop.ToMap[K, V]) 194 } 195 196 // ConvertValue returns a stream that applies the 'converter' function to values of the map 197 func (m Map[K, V]) ConvertValue(converter func(V) V) stream.Iter[K, V, map[K]V] { 198 h := m.Head() 199 return stream.New(loop.Convert(h.Next, convert.Value[K](converter)).Next, loop.ToMap[K, V]) 200 } 201 202 // ConvValue returns a breakable stream that applies the 'converter' function to values of the map 203 func (m Map[K, V]) ConvValue(converter func(V) (V, error)) kvstream.Iter[K, V, map[K]V] { 204 h := m.Head() 205 return kvstream.New(breakLoop.Conv(breakLoop.From(h.Next), breakMapConvert.Value[K](converter)).Next, breakLoop.ToMap[K, V]) 206 } 207 208 // Filter returns a stream consisting of elements that satisfy the condition of the 'predicate' function 209 func (m Map[K, V]) Filter(predicate func(K, V) bool) stream.Iter[K, V, map[K]V] { 210 h := m.Head() 211 return stream.New(loop.Filter(h.Next, predicate).Next, loop.ToMap[K, V]) 212 } 213 214 // Filt returns a breakable stream consisting of elements that satisfy the condition of the 'predicate' function 215 func (m Map[K, V]) Filt(predicate func(K, V) (bool, error)) kvstream.Iter[K, V, map[K]V] { 216 h := m.Head() 217 return kvstream.New(breakLoop.Filt(breakLoop.From(h.Next), predicate).Next, breakLoop.ToMap[K, V]) 218 } 219 220 // Convert returns a stream that applies the 'converter' function to the collection elements 221 func (m Map[K, V]) Convert(converter func(K, V) (K, V)) stream.Iter[K, V, map[K]V] { 222 h := m.Head() 223 return stream.New(loop.Convert(h.Next, converter).Next, loop.ToMap[K, V]) 224 } 225 226 // Conv returns a breakable stream that applies the 'converter' function to the collection elements 227 func (m Map[K, V]) Conv(converter func(K, V) (K, V, error)) kvstream.Iter[K, V, map[K]V] { 228 h := m.Head() 229 return kvstream.New(breakLoop.Conv(breakLoop.From(h.Next), converter).Next, breakLoop.ToMap[K, V]) 230 } 231 232 // Reduce reduces the key/value pairs of the map into an one pair using the 'merge' function 233 func (m Map[K, V]) Reduce(merge func(K, K, V, V) (K, V)) (K, V) { 234 return map_.Reduce(m.elements, merge) 235 } 236 237 // HasAny finds the first key/value pair that satisfies the 'predicate' function condition and returns true if successful 238 func (m Map[K, V]) HasAny(predicate func(K, V) bool) bool { 239 return map_.HasAny(m.elements, predicate) 240 } 241 242 func addToMap[K comparable, V any](key K, val V, order []K, uniques map[K]V) []K { 243 if _, ok := uniques[key]; !ok { 244 order = append(order, key) 245 uniques[key] = val 246 } 247 return order 248 }