github.com/m4gshm/gollections@v0.0.10/kv/stream/stream.go (about)

     1  package stream
     2  
     3  import (
     4  	breakKvLoop "github.com/m4gshm/gollections/break/kv/loop"
     5  	"github.com/m4gshm/gollections/break/kv/stream"
     6  	breakMapConvert "github.com/m4gshm/gollections/break/map_/convert"
     7  	breakFilter "github.com/m4gshm/gollections/break/map_/filter"
     8  	"github.com/m4gshm/gollections/kv"
     9  	kvloop "github.com/m4gshm/gollections/kv/loop"
    10  	"github.com/m4gshm/gollections/loop"
    11  	"github.com/m4gshm/gollections/map_/convert"
    12  	"github.com/m4gshm/gollections/map_/filter"
    13  )
    14  
    15  // New instantiates StreamIter
    16  func New[K comparable, V any, M map[K]V | map[K][]V](next func() (K, V, bool), collector MapCollector[K, V, M]) Iter[K, V, M] {
    17  	return Iter[K, V, M]{next: next, collector: collector}
    18  }
    19  
    20  // Iter is the key/value Iterator based stream implementation.
    21  type Iter[K comparable, V any, M map[K]V | map[K][]V] struct {
    22  	next      func() (K, V, bool)
    23  	collector MapCollector[K, V, M]
    24  }
    25  
    26  var (
    27  	_ kv.Iterator[string, any]                                        = (*Iter[string, any, map[string]any])(nil)
    28  	_ Stream[string, any, map[string]any]                             = (*Iter[string, any, map[string]any])(nil)
    29  	_ Stream[string, any, map[string][]any]                           = (*Iter[string, any, map[string][]any])(nil)
    30  	_ kvloop.Looper[string, any, Iter[string, any, map[string]any]]   = (*Iter[string, any, map[string]any])(nil)
    31  	_ kvloop.Looper[string, any, Iter[string, any, map[string][]any]] = (*Iter[string, any, map[string][]any])(nil)
    32  
    33  	_ kv.Iterator[string, any]                                        = Iter[string, any, map[string]any]{}
    34  	_ Stream[string, any, map[string]any]                             = Iter[string, any, map[string]any]{}
    35  	_ Stream[string, any, map[string][]any]                           = Iter[string, any, map[string][]any]{}
    36  	_ kvloop.Looper[string, any, Iter[string, any, map[string]any]]   = Iter[string, any, map[string]any]{}
    37  	_ kvloop.Looper[string, any, Iter[string, any, map[string][]any]] = Iter[string, any, map[string][]any]{}
    38  	_ kv.IterFor[string, any, Iter[string, any, map[string][]any]]    = Iter[string, any, map[string][]any]{}
    39  )
    40  
    41  // Next implements kv.KVIterator
    42  func (i Iter[K, V, M]) Next() (K, V, bool) {
    43  	return i.next()
    44  }
    45  
    46  // FilterKey returns a stream consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
    47  func (i Iter[K, V, M]) FilterKey(predicate func(K) bool) Iter[K, V, M] {
    48  	return New(kvloop.Filter(i.next, filter.Key[V](predicate)).Next, i.collector)
    49  }
    50  
    51  // FiltKey returns a stream consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
    52  func (i Iter[K, V, M]) FiltKey(predicate func(K) (bool, error)) stream.Iter[K, V, M] {
    53  	return stream.New(breakKvLoop.Filt(breakKvLoop.From(i.next), breakFilter.Key[V](predicate)).Next, collect(i.collector))
    54  }
    55  
    56  // ConvertKey returns a stream that applies the 'converter' function to keys of the map
    57  func (i Iter[K, V, M]) ConvertKey(by func(K) K) Iter[K, V, M] {
    58  	return New(kvloop.Convert(i.next, convert.Key[V](by)).Next, i.collector)
    59  }
    60  
    61  // ConvKey returns a stream that applies the 'converter' function to keys of the map
    62  func (i Iter[K, V, M]) ConvKey(by func(K) (K, error)) stream.Iter[K, V, M] {
    63  	return stream.New(breakKvLoop.Conv(breakKvLoop.From(i.next), breakMapConvert.Key[V](by)).Next, collect(i.collector))
    64  }
    65  
    66  // FilterValue returns a stream consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
    67  func (i Iter[K, V, M]) FilterValue(predicate func(V) bool) Iter[K, V, M] {
    68  	return New(kvloop.Filter(i.next, filter.Value[K](predicate)).Next, i.collector)
    69  }
    70  
    71  // FiltValue returns a stream consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
    72  func (i Iter[K, V, M]) FiltValue(predicate func(V) (bool, error)) stream.Iter[K, V, M] {
    73  	return stream.New(breakKvLoop.Filt(breakKvLoop.From(i.next), breakFilter.Value[K](predicate)).Next, collect(i.collector))
    74  }
    75  
    76  // ConvertValue returns a stream that applies the 'converter' function to values of the map
    77  func (i Iter[K, V, M]) ConvertValue(converter func(V) V) Iter[K, V, M] {
    78  	return New(kvloop.Convert(i.next, convert.Value[K](converter)).Next, i.collector)
    79  }
    80  
    81  // ConvValue returns a stream that applies the 'converter' function to values of the map
    82  func (i Iter[K, V, M]) ConvValue(converter func(V) (V, error)) stream.Iter[K, V, M] {
    83  	return stream.New(breakKvLoop.Conv(breakKvLoop.From(i.next), breakMapConvert.Value[K](converter)).Next, collect(i.collector))
    84  }
    85  
    86  // Filter returns a stream consisting of elements that satisfy the condition of the 'predicate' function
    87  func (i Iter[K, V, M]) Filter(predicate func(K, V) bool) Iter[K, V, M] {
    88  	return New(kvloop.Filter(i.next, predicate).Next, i.collector)
    89  }
    90  
    91  // Filt returns a breakable stream consisting of elements that satisfy the condition of the 'predicate' function
    92  func (i Iter[K, V, M]) Filt(predicate func(K, V) (bool, error)) stream.Iter[K, V, M] {
    93  	return stream.New(breakKvLoop.Filt(breakKvLoop.From(i.next), predicate).Next, collect(i.collector))
    94  }
    95  
    96  // Convert returns a stream that applies the 'converter' function to the collection elements
    97  func (i Iter[K, V, M]) Convert(converter func(K, V) (K, V)) Iter[K, V, M] {
    98  	return New(kvloop.Convert(i.next, converter).Next, i.collector)
    99  }
   100  
   101  // Conv returns a breakable stream that applies the 'converter' function to the collection elements
   102  func (i Iter[K, V, M]) Conv(converter func(K, V) (K, V, error)) stream.Iter[K, V, M] {
   103  	return stream.New(breakKvLoop.Conv(breakKvLoop.From(i.next), converter).Next, collect(i.collector))
   104  }
   105  
   106  // Track applies the 'tracker' function for key/value pairs. Return the c.ErrBreak to stop.
   107  func (i Iter[K, V, M]) Track(tracker func(K, V) error) error {
   108  	return loop.Track(i.next, tracker)
   109  }
   110  
   111  // TrackEach applies the 'tracker' function for every key/value pairs
   112  func (i Iter[K, V, M]) TrackEach(tracker func(K, V)) {
   113  	loop.TrackEach(i.next, tracker)
   114  }
   115  
   116  // Reduce reduces the key/value pairs into an one pair using the 'merge' function
   117  func (i Iter[K, V, M]) Reduce(by func(K, K, V, V) (K, V)) (K, V) {
   118  	return kvloop.Reduce(i.next, by)
   119  }
   120  
   121  // HasAny finds the first key/value pari that satisfies the 'predicate' function condition and returns true if successful
   122  func (i Iter[K, V, M]) HasAny(predicate func(K, V) bool) bool {
   123  	next := i.next
   124  	return kvloop.HasAny(next, predicate)
   125  }
   126  
   127  // Iter creates an iterator and returns as interface
   128  func (i Iter[K, V, M]) Iter() kv.Iterator[K, V] {
   129  	return i
   130  }
   131  
   132  // Loop creates an iterator and returns as implementation type reference
   133  func (i Iter[K, V, M]) Loop() Iter[K, V, M] {
   134  	return i
   135  }
   136  
   137  // Map collects the key/value pairs to a map
   138  func (i Iter[K, V, M]) Map() M {
   139  	return i.collector(i.next)
   140  }
   141  
   142  // Start is used with for loop construct like 'for i, k, v, ok := i.Start(); ok; k, v, ok = i.Next() { }'
   143  func (i Iter[K, V, M]) Start() (Iter[K, V, M], K, V, bool) {
   144  	k, v, ok := i.Next()
   145  	return i, k, v, ok
   146  }
   147  
   148  // MapCollector is Converter of key/value Iterator that collects all values to any slice or map, mostly used to extract slice fields to flatting a result
   149  type MapCollector[K comparable, V any, M map[K]V | map[K][]V] func(next func() (K, V, bool)) M
   150  
   151  func collect[K comparable, V any, M map[K]V | map[K][]V](collector MapCollector[K, V, M]) stream.MapCollector[K, V, M] {
   152  	return func(next func() (K, V, bool, error)) (M, error) {
   153  		var loopErr error
   154  		breakKvLoop.To(next, func(err error) { loopErr = err })
   155  		return collector(breakKvLoop.To(next, func(err error) { loopErr = err })), loopErr
   156  	}
   157  }