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