github.com/m4gshm/gollections@v0.0.13-0.20240331203319-a34a86e58a24/collection/immutable/map.go (about) 1 package immutable 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 Map using a map as internal storage. 20 func WrapMap[K comparable, V any](elements map[K]V) Map[K, V] { 21 return Map[K, V]{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 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, any], MapValues[int, any]] = (*Map[int, any])(nil) 33 _ c.KeyVal[MapKeys[int, any], 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 K, v V) bool) { 40 for k, v := range m.elements { 41 if !consumer(k, v) { 42 break 43 } 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() map_.Iter[K, V] { 56 return map_.NewIter(m.elements) 57 } 58 59 // Deprecated: First is deprecated. Will be replaced by rance-over function iterator. 60 // 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. 61 // If no more then ok==false. 62 func (m Map[K, V]) First() (map_.Iter[K, V], K, V, bool) { 63 var ( 64 iterator = m.Head() 65 firstK, firstV, ok = iterator.Next() 66 ) 67 return iterator, firstK, firstV, ok 68 } 69 70 // Map collects the key/value pairs to a map 71 func (m Map[K, V]) Map() map[K]V { 72 return map_.Clone(m.elements) 73 } 74 75 // Len returns amount of elements 76 func (m Map[K, V]) Len() int { 77 return len(m.elements) 78 } 79 80 // IsEmpty returns true if the map is empty 81 func (m Map[K, V]) IsEmpty() bool { 82 return m.Len() == 0 83 } 84 85 // Contains checks is the map contains a key 86 func (m Map[K, V]) Contains(key K) (ok bool) { 87 if m.elements != nil { 88 _, ok = m.elements[key] 89 } 90 return ok 91 } 92 93 // Get returns the value for a key. 94 // If ok==false, then the map does not contain the key. 95 func (m Map[K, V]) Get(key K) (element V, ok bool) { 96 if m.elements != nil { 97 element, ok = m.elements[key] 98 } 99 return element, ok 100 } 101 102 // Keys resutrns keys collection 103 func (m Map[K, V]) Keys() MapKeys[K, V] { 104 return m.K() 105 } 106 107 // K resutrns keys collection impl 108 func (m Map[K, V]) K() MapKeys[K, V] { 109 return WrapKeys(m.elements) 110 } 111 112 // Values resutrns values collection 113 func (m Map[K, V]) Values() MapValues[K, V] { 114 return m.V() 115 } 116 117 // V resutrns values collection impl 118 func (m Map[K, V]) V() MapValues[K, V] { 119 return WrapVal(m.elements) 120 } 121 122 // Sort returns sorted by keys map 123 func (m Map[K, V]) Sort(comparer slice.Comparer[K]) ordered.Map[K, V] { 124 return m.sortBy(slice.Sort, comparer) 125 } 126 127 // StableSort returns sorted by keys map 128 func (m Map[K, V]) StableSort(comparer slice.Comparer[K]) ordered.Map[K, V] { 129 return m.sortBy(slice.StableSort, comparer) 130 } 131 132 func (m Map[K, V]) sortBy(sorter func([]K, slice.Comparer[K]) []K, comparer slice.Comparer[K]) ordered.Map[K, V] { 133 return ordered.WrapMap(sorter(map_.Keys(m.elements), comparer), m.elements) 134 } 135 136 func (m Map[K, V]) String() string { 137 return map_.ToString(m.elements) 138 } 139 140 // Track applies the 'consumer' function for all key/value pairs until the consumer returns the c.Break to stop. 141 func (m Map[K, V]) Track(consumer func(K, V) error) error { 142 return map_.Track(m.elements, consumer) 143 } 144 145 // TrackEach applies the 'consumer' function for every key/value pairs 146 func (m Map[K, V]) TrackEach(consumer func(K, V)) { 147 map_.TrackEach(m.elements, consumer) 148 } 149 150 // FilterKey returns a loop consisting of key/value pairs where the key satisfies the condition of the 'predicate' function 151 func (m Map[K, V]) FilterKey(predicate func(K) bool) loop.Loop[K, V] { 152 return loop.Filter(m.Loop(), filter.Key[V](predicate)) 153 } 154 155 // FiltKey returns a loop consisting of key/value pairs where the key satisfies the condition of the 'predicate' function 156 func (m Map[K, V]) FiltKey(predicate func(K) (bool, error)) breakLoop.Loop[K, V] { 157 return loop.Filt(m.Loop(), breakMapFilter.Key[V](predicate)) 158 } 159 160 // ConvertKey returns a loop that applies the 'converter' function to keys of the map 161 func (m Map[K, V]) ConvertKey(by func(K) K) loop.Loop[K, V] { 162 return loop.Convert(m.Loop(), convert.Key[V](by)) 163 } 164 165 // ConvKey returns a loop that applies the 'converter' function to keys of the map 166 func (m Map[K, V]) ConvKey(converter func(K) (K, error)) breakLoop.Loop[K, V] { 167 return loop.Conv(m.Loop(), breakMapConvert.Key[V](converter)) 168 } 169 170 // FilterValue returns a loop consisting of key/value pairs where the value satisfies the condition of the 'predicate' function 171 func (m Map[K, V]) FilterValue(predicate func(V) bool) loop.Loop[K, V] { 172 return loop.Filter(m.Loop(), filter.Value[K](predicate)) 173 } 174 175 // FiltValue returns a loop consisting of key/value pairs where the value satisfies the condition of the 'predicate' function 176 func (m Map[K, V]) FiltValue(predicate func(V) (bool, error)) breakLoop.Loop[K, V] { 177 return loop.Filt(m.Loop(), breakMapFilter.Value[K](predicate)) 178 } 179 180 // ConvertValue returns a loop that applies the 'converter' function to values of the map 181 func (m Map[K, V]) ConvertValue(by func(V) V) loop.Loop[K, V] { 182 return loop.Convert(m.Loop(), convert.Value[K](by)) 183 } 184 185 // ConvValue returns a loop that applies the 'converter' function to values of the map 186 func (m Map[K, V]) ConvValue(converter func(V) (V, error)) breakLoop.Loop[K, V] { 187 return loop.Conv(m.Loop(), 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) loop.Loop[K, V] { 192 return loop.Filter(m.Loop(), predicate) 193 } 194 195 // Filt returns a breakable loop consisting of elements that satisfy the condition of the 'predicate' function 196 func (m Map[K, V]) Filt(predicate func(K, V) (bool, error)) breakLoop.Loop[K, V] { 197 return loop.Filt(m.Loop(), predicate) 198 } 199 200 // Convert returns a loop that applies the 'converter' function to the collection elements 201 func (m Map[K, V]) Convert(converter func(K, V) (K, V)) loop.Loop[K, V] { 202 return loop.Convert(m.Loop(), converter) 203 } 204 205 // Conv returns a breakable loop that applies the 'converter' function to the collection elements 206 func (m Map[K, V]) Conv(converter func(K, V) (K, V, error)) breakLoop.Loop[K, V] { 207 return loop.Conv(m.Loop(), converter) 208 } 209 210 // Reduce reduces the key/value pairs of the map into an one pair using the 'merge' function 211 func (m Map[K, V]) Reduce(merge func(K, K, V, V) (K, V)) (K, V) { 212 return map_.Reduce(m.elements, merge) 213 } 214 215 // HasAny finds the first key/value pair that satisfies the 'predicate' function condition and returns true if successful 216 func (m Map[K, V]) HasAny(predicate func(K, V) bool) bool { 217 return map_.HasAny(m.elements, predicate) 218 }