github.com/m4gshm/gollections@v0.0.10/collection/immutable/ordered/values.go (about) 1 package ordered 2 3 import ( 4 "fmt" 5 6 breakLoop "github.com/m4gshm/gollections/break/loop" 7 breakStream "github.com/m4gshm/gollections/break/stream" 8 "github.com/m4gshm/gollections/c" 9 "github.com/m4gshm/gollections/collection" 10 "github.com/m4gshm/gollections/loop" 11 "github.com/m4gshm/gollections/map_" 12 "github.com/m4gshm/gollections/slice" 13 "github.com/m4gshm/gollections/stream" 14 ) 15 16 // WrapVal instantiates MapValues using elements as internal storage. 17 func WrapVal[K comparable, V any](order []K, elements map[K]V) MapValues[K, V] { 18 return MapValues[K, V]{order, elements} 19 } 20 21 // MapValues is the wrapper for Map'm values. 22 type MapValues[K comparable, V any] struct { 23 order []K 24 elements map[K]V 25 } 26 27 var ( 28 _ c.Collection[any] = (*MapValues[int, any])(nil) 29 _ loop.Looper[any, *ValIter[int, any]] = (*MapValues[int, any])(nil) 30 _ fmt.Stringer = (*MapValues[int, any])(nil) 31 ) 32 33 // Iter creates an iterator and returns as interface 34 func (m MapValues[K, V]) Iter() c.Iterator[V] { 35 h := m.Head() 36 return &h 37 } 38 39 // Loop creates an iterator and returns as implementation type reference 40 func (m MapValues[K, V]) Loop() *ValIter[K, V] { 41 h := m.Head() 42 return &h 43 } 44 45 // Head creates an iterator and returns as implementation type value 46 func (m MapValues[K, V]) Head() ValIter[K, V] { 47 var ( 48 order []K 49 elements map[K]V 50 ) 51 52 order = m.order 53 elements = m.elements 54 55 return NewValIter(order, elements) 56 } 57 58 // First returns the first element of the collection, an iterator to iterate over the remaining elements, and true\false marker of availability next elements. 59 // If no more elements then ok==false. 60 func (m MapValues[K, V]) First() (ValIter[K, V], V, bool) { 61 var ( 62 iterator = m.Head() 63 first, ok = iterator.Next() 64 ) 65 return iterator, first, ok 66 } 67 68 // Len returns amount of elements 69 func (m MapValues[K, V]) Len() int { 70 return len(m.elements) 71 } 72 73 // IsEmpty returns true if the collection is empty 74 func (m MapValues[K, V]) IsEmpty() bool { 75 return m.Len() == 0 76 } 77 78 // Slice collects the values to a slice 79 func (m MapValues[K, V]) Slice() (values []V) { 80 return m.Append(values) 81 } 82 83 // Append collects the values to the specified 'out' slice 84 func (m MapValues[K, V]) Append(out []V) (values []V) { 85 for _, key := range m.order { 86 val := m.elements[key] 87 out = append(out, val) 88 } 89 return out 90 } 91 92 // For applies the 'walker' function for every value. Return the c.ErrBreak to stop. 93 func (m MapValues[K, V]) For(walker func(V) error) error { 94 return map_.ForOrderedValues(m.order, m.elements, walker) 95 } 96 97 // ForEach applies the 'walker' function for every value 98 func (m MapValues[K, V]) ForEach(walker func(V)) { 99 map_.ForEachOrderedValues(m.order, m.elements, walker) 100 } 101 102 // Get returns an element by the index, otherwise, if the provided index is ouf of the collection len, returns zero T and false in the second result 103 func (m MapValues[K, V]) Get(index int) (V, bool) { 104 keys := m.order 105 if index >= 0 && index < len(keys) { 106 key := keys[index] 107 val, ok := m.elements[key] 108 return val, ok 109 } 110 var no V 111 return no, false 112 } 113 114 // Filter returns a stream consisting of elements that satisfy the condition of the 'predicate' function 115 func (m MapValues[K, V]) Filter(filter func(V) bool) stream.Iter[V] { 116 h := m.Head() 117 return stream.New(loop.Filter(h.Next, filter).Next) 118 } 119 120 // Filt returns a breakable stream consisting of elements that satisfy the condition of the 'predicate' function 121 func (m MapValues[K, V]) Filt(filter func(V) (bool, error)) breakStream.Iter[V] { 122 h := m.Head() 123 return breakStream.New(breakLoop.Filt(breakLoop.From(h.Next), filter).Next) 124 } 125 126 // Convert returns a stream that applies the 'converter' function to the collection elements 127 func (m MapValues[K, V]) Convert(converter func(V) V) stream.Iter[V] { 128 return collection.Convert(m, converter) 129 } 130 131 // Conv returns a breakable stream that applies the 'converter' function to the collection elements 132 func (m MapValues[K, V]) Conv(converter func(V) (V, error)) breakStream.Iter[V] { 133 return collection.Conv(m, converter) 134 } 135 136 // Reduce reduces the elements into an one using the 'merge' function 137 func (m MapValues[K, V]) Reduce(merge func(V, V) V) V { 138 _, v := map_.Reduce(m.elements, func(_, _ K, v1, v2 V) (k K, v V) { 139 return k, merge(v1, v2) 140 }) 141 return v 142 } 143 144 // HasAny finds the first element that satisfies the 'predicate' function condition and returns true if successful 145 func (m MapValues[K, V]) HasAny(predicate func(V) bool) bool { 146 return map_.HasAny(m.elements, func(_ K, v V) bool { 147 return predicate(v) 148 }) 149 } 150 151 func (m MapValues[K, V]) String() string { 152 return slice.ToString(m.Slice()) 153 }