github.com/m4gshm/gollections@v0.0.10/collection/api.go (about) 1 // Package collection consists of common operations of c.Iterable based collections 2 package collection 3 4 import ( 5 "golang.org/x/exp/constraints" 6 7 breakloop "github.com/m4gshm/gollections/break/loop" 8 breakstream "github.com/m4gshm/gollections/break/stream" 9 "github.com/m4gshm/gollections/c" 10 "github.com/m4gshm/gollections/convert" 11 "github.com/m4gshm/gollections/convert/as" 12 kvloop "github.com/m4gshm/gollections/kv/loop" 13 kvstream "github.com/m4gshm/gollections/kv/stream" 14 "github.com/m4gshm/gollections/loop" 15 loopconvert "github.com/m4gshm/gollections/loop/convert" 16 "github.com/m4gshm/gollections/op/check/not" 17 "github.com/m4gshm/gollections/slice" 18 "github.com/m4gshm/gollections/stream" 19 ) 20 21 // Convert returns a stream that applies the 'converter' function to the collection elements 22 func Convert[From, To any, I c.Iterable[From]](collection I, converter func(From) To) stream.Iter[To] { 23 b := collection.Iter() 24 return stream.New(loop.Convert(b.Next, converter).Next) 25 } 26 27 // Conv returns a breakable stream that applies the 'converter' function to the collection elements 28 func Conv[From, To any, I c.Iterable[From]](collection I, converter func(From) (To, error)) breakstream.Iter[To] { 29 b := collection.Iter() 30 return breakstream.New(breakloop.Conv(breakloop.From(b.Next), converter).Next) 31 } 32 33 // FilterAndConvert returns a stream that filters source elements and converts them 34 func FilterAndConvert[From, To any, I c.Iterable[From]](collection I, filter func(From) bool, converter func(From) To) stream.Iter[To] { 35 b := collection.Iter() 36 f := loop.FilterAndConvert(b.Next, filter, converter) 37 return stream.New(f.Next) 38 } 39 40 // Flat returns a stream that converts the collection elements into slices and then flattens them to one level 41 func Flat[From, To any, I c.Iterable[From]](collection I, by func(From) []To) stream.Iter[To] { 42 b := collection.Iter() 43 f := loop.Flat(b.Next, by) 44 return stream.New(f.Next) 45 } 46 47 // Flatt returns a breakable stream that converts the collection elements into slices and then flattens them to one level 48 func Flatt[From, To comparable, I c.Iterable[From]](collection I, flattener func(From) ([]To, error)) breakstream.Iter[To] { 49 h := collection.Iter() 50 f := breakloop.Flatt(breakloop.From(h.Next), flattener) 51 return breakstream.New(f.Next) 52 } 53 54 // FilterAndFlat filters source elements and extracts slices of 'To' by the 'flattener' function 55 func FilterAndFlat[From, To any, I c.Iterable[From]](collection I, filter func(From) bool, flattener func(From) []To) stream.Iter[To] { 56 b := collection.Iter() 57 f := loop.FilterAndFlat(b.Next, filter, flattener) 58 return stream.New(f.Next) 59 } 60 61 // Filter instantiates a stream that checks elements by the 'filter' function and returns successful ones 62 func Filter[T any, I c.Iterable[T]](collection I, filter func(T) bool) stream.Iter[T] { 63 b := collection.Iter() 64 f := loop.Filter(b.Next, filter) 65 return stream.New(f.Next) 66 } 67 68 // NotNil instantiates a stream that filters nullable elements 69 func NotNil[T any, I c.Iterable[*T]](collection I) stream.Iter[*T] { 70 return Filter(collection, not.Nil[T]) 71 } 72 73 // PtrVal creates a stream that transform pointers to the values referenced referenced by those pointers. 74 // Nil pointers are transformet to zero values. 75 func PtrVal[T any, I c.Iterable[*T]](collection I) stream.Iter[T] { 76 return stream.New(loop.PtrVal(collection.Iter().Next).Next) 77 } 78 79 // NoNilPtrVal creates a stream that transform only not nil pointers to the values referenced referenced by those pointers. 80 // Nil pointers are ignored. 81 func NoNilPtrVal[T any, I c.Iterable[*T]](collection I) stream.Iter[T] { 82 return stream.New(loop.NoNilPtrVal(collection.Iter().Next).Next) 83 } 84 85 // NilSafe creates a stream that filters not nil elements, converts that ones, filters not nils after converting and returns them 86 func NilSafe[From, To any, I c.Iterable[*From]](collection I, converter func(*From) *To) stream.Iter[*To] { 87 h := collection.Iter() 88 return stream.New(loopconvert.NilSafe(h.Next, converter).Next) 89 } 90 91 // KeyValue transforms iterable elements to key/value iterator based on applying key, value extractors to the elements 92 func KeyValue[T, K, V any, I c.Iterable[T]](collection I, keyExtractor func(T) K, valExtractor func(T) V) loop.KeyValuer[T, K, V] { 93 h := collection.Iter() 94 return loop.KeyValue(h.Next, keyExtractor, valExtractor) 95 } 96 97 // KeyValuee transforms iterable elements to key/value iterator based on applying key, value extractors to the elements 98 func KeyValuee[T, K, V any, I c.Iterable[T]](collection I, keyExtractor func(T) (K, error), valExtractor func(T) (V, error)) breakloop.KeyValuer[T, K, V] { 99 h := collection.Iter() 100 return loop.KeyValuee(h.Next, keyExtractor, valExtractor) 101 } 102 103 // KeysValues transforms iterable elements to key/value iterator based on applying multiple keys, values extractor to the elements 104 func KeysValues[T, K, V any, I c.Iterable[T]](collection I, keysExtractor func(T) []K, valsExtractor func(T) []V) *loop.MultipleKeyValuer[T, K, V] { 105 h := collection.Iter() 106 return loop.NewMultipleKeyValuer(h.Next, keysExtractor, valsExtractor) 107 } 108 109 // KeysValue transforms iterable elements to key/value iterator based on applying keys, value extractor to the elements 110 func KeysValue[T, K, V any, I c.Iterable[T]](collection I, keysExtractor func(T) []K, valExtractor func(T) V) *loop.MultipleKeyValuer[T, K, V] { 111 h := collection.Iter() 112 return loop.KeysValues(h.Next, keysExtractor, func(t T) []V { return convert.AsSlice(valExtractor(t)) }) 113 } 114 115 // KeysValuee transforms iterable elements to key/value iterator based on applying keys, value extractor to the elements 116 func KeysValuee[T, K, V any, I c.Iterable[T]](collection I, keysExtractor func(T) ([]K, error), valExtractor func(T) (V, error)) *breakloop.MultipleKeyValuer[T, K, V] { 117 h := collection.Iter() 118 return loop.KeysValuee(h.Next, keysExtractor, valExtractor) 119 } 120 121 // KeyValues transforms iterable elements to key/value iterator based on applying key, values extractor to the elements 122 func KeyValues[T, K, V any, I c.Iterable[T]](collection I, keyExtractor func(T) K, valsExtractor func(T) []V) *loop.MultipleKeyValuer[T, K, V] { 123 h := collection.Iter() 124 return loop.KeysValues(h.Next, func(t T) []K { return convert.AsSlice(keyExtractor(t)) }, valsExtractor) 125 } 126 127 // KeyValuess transforms iterable elements to key/value iterator based on applying key, values extractor to the elements 128 func KeyValuess[T, K, V any, I c.Iterable[T]](collection I, keyExtractor func(T) (K, error), valsExtractor func(T) ([]V, error)) *breakloop.MultipleKeyValuer[T, K, V] { 129 h := collection.Iter() 130 return loop.KeyValuess(h.Next, keyExtractor, valsExtractor) 131 } 132 133 // ExtraVals transforms iterable elements to key/value iterator based on applying values extractor to the elements 134 func ExtraVals[T, V any, I c.Iterable[T]](collection I, valsExtractor func(T) []V) *loop.MultipleKeyValuer[T, T, V] { 135 h := collection.Iter() 136 return loop.KeyValues(h.Next, as.Is[T], valsExtractor) 137 } 138 139 // ExtraValss transforms iterable elements to key/value iterator based on applying values extractor to the elements 140 func ExtraValss[T, V any, I c.Iterable[T]](collection I, valsExtractor func(T) ([]V, error)) *breakloop.MultipleKeyValuer[T, T, V] { 141 h := collection.Iter() 142 return loop.KeyValuess(h.Next, as.ErrTail(as.Is[T]), valsExtractor) 143 } 144 145 // ExtraKeys transforms iterable elements to key/value iterator based on applying key extractor to the elements 146 func ExtraKeys[T, K any, I c.Iterable[T]](collection I, keysExtractor func(T) []K) *loop.MultipleKeyValuer[T, K, T] { 147 h := collection.Iter() 148 return loop.KeysValue(h.Next, keysExtractor, as.Is[T]) 149 } 150 151 // ExtraKeyss transforms iterable elements to key/value iterator based on applying key extractor to the elements 152 func ExtraKeyss[T, K any, I c.Iterable[T]](collection I, keyExtractor func(T) (K, error)) *breakloop.MultipleKeyValuer[T, K, T] { 153 h := collection.Iter() 154 return loop.KeyValuess(h.Next, keyExtractor, as.ErrTail(convert.AsSlice[T])) 155 } 156 157 // ExtraKey transforms iterable elements to key/value iterator based on applying key extractor to the elements 158 func ExtraKey[T, K any, I c.Iterable[T]](collection I, keysExtractor func(T) K) loop.KeyValuer[T, K, T] { 159 h := collection.Iter() 160 return loop.KeyValue(h.Next, keysExtractor, as.Is[T]) 161 } 162 163 // ExtraKeyy transforms iterable elements to key/value iterator based on applying key extractor to the elements 164 func ExtraKeyy[T, K any, I c.Iterable[T]](collection I, keyExtractor func(T) (K, error)) breakloop.KeyValuer[T, K, T] { 165 h := collection.Iter() 166 return loop.ExtraKeyy(h.Next, keyExtractor) 167 } 168 169 // ExtraValue transforms iterable elements to key/value iterator based on applying value extractor to the elements 170 func ExtraValue[T, V any, I c.Iterable[T]](collection I, valueExtractor func(T) V) loop.KeyValuer[T, T, V] { 171 h := collection.Iter() 172 return loop.ExtraValue(h.Next, valueExtractor) 173 } 174 175 // ExtraValuee transforms iterable elements to key/value iterator based on applying value extractor to the elements 176 func ExtraValuee[T, V any, I c.Iterable[T]](collection I, valExtractor func(T) (V, error)) breakloop.KeyValuer[T, T, V] { 177 h := collection.Iter() 178 return loop.ExtraValuee(h.Next, valExtractor) 179 } 180 181 // Group groups elements to slices by a converter and returns a map 182 func Group[T any, K comparable, I c.Iterable[T]](collection I, by func(T) K) kvstream.Iter[K, T, map[K][]T] { 183 it := loop.NewKeyValuer(collection.Iter().Next, by, as.Is[T]) 184 return kvstream.New(it.Next, kvloop.Group[K, T]) 185 } 186 187 // First returns the first element that satisfies the condition of the 'predicate' function 188 func First[T any, I c.Iterable[T]](collection I, predicate func(T) bool) (v T, ok bool) { 189 i := collection.Iter() 190 return loop.First(i.Next, predicate) 191 } 192 193 // Firstt returns the first element that satisfies the condition of the 'predicate' function 194 func Firstt[T any, I c.Iterable[T]](collection I, predicate func(T) (bool, error)) (v T, ok bool, err error) { 195 i := collection.Iter() 196 return breakloop.Firstt(breakloop.From(i.Next), predicate) 197 } 198 199 // Sort sorts the specified sortable collection that contains orderable elements 200 func Sort[O any, S interface{ Sort(less slice.Less[T]) O }, T any, f constraints.Ordered](collection S, by func(T) f) O { 201 return collection.Sort(func(e1, e2 T) bool { return by(e1) < by(e2) }) 202 }