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  }