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

     1  // Package stream provides a stream implementation and helper functions
     2  package stream
     3  
     4  import (
     5  	"github.com/m4gshm/gollections/break/kv"
     6  	"github.com/m4gshm/gollections/break/kv/loop"
     7  	breakLoop "github.com/m4gshm/gollections/break/loop"
     8  	breakFilter "github.com/m4gshm/gollections/break/map_/filter"
     9  	"github.com/m4gshm/gollections/map_/filter"
    10  )
    11  
    12  // New is the main stream constructor
    13  func New[K comparable, V any, M map[K]V | map[K][]V](next func() (K, V, bool, error), collector MapCollector[K, V, M]) Iter[K, V, M] {
    14  	return Iter[K, V, M]{next: next, collector: collector}
    15  }
    16  
    17  // Iter is the key/value Iterator based stream implementation.
    18  type Iter[K comparable, V any, M map[K]V | map[K][]V] struct {
    19  	next      func() (K, V, bool, error)
    20  	collector MapCollector[K, V, M]
    21  }
    22  
    23  var (
    24  	_ kv.Iterator[string, any]              = (*Iter[string, any, map[string]any])(nil)
    25  	_ Stream[string, any, map[string]any]   = (*Iter[string, any, map[string]any])(nil)
    26  	_ Stream[string, any, map[string][]any] = (*Iter[string, any, map[string][]any])(nil)
    27  
    28  	_ kv.Iterator[string, any]              = Iter[string, any, map[string]any]{}
    29  	_ Stream[string, any, map[string]any]   = Iter[string, any, map[string]any]{}
    30  	_ Stream[string, any, map[string][]any] = Iter[string, any, map[string][]any]{}
    31  )
    32  
    33  var _ kv.IterFor[string, any, Iter[string, any, map[string]any]] = Iter[string, any, map[string]any]{}
    34  
    35  // Next implements kv.KVIterator
    36  func (i Iter[K, V, M]) Next() (K, V, bool, error) {
    37  	return i.next()
    38  }
    39  
    40  // FilterKey returns a stream consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
    41  func (i Iter[K, V, M]) FilterKey(predicate func(K) bool) Iter[K, V, M] {
    42  	return New(loop.Filter(i.next, filter.Key[V](predicate)).Next, i.collector)
    43  }
    44  
    45  // FiltKey returns a stream consisting of key/value pairs where the key satisfies the condition of the 'predicate' function
    46  func (i Iter[K, V, M]) FiltKey(predicate func(K) (bool, error)) Iter[K, V, M] {
    47  	return New(loop.Filt(i.next, breakFilter.Key[V](predicate)).Next, i.collector)
    48  }
    49  
    50  // // ConvertKey returns a stream that applies the 'converter' function to keys of the map
    51  // func (i StreamIter[K, V, M]) ConvertKey(by func(K) K) Iter[K, V, M] {
    52  // 	return Stream(Convert(i.next, convert.Key[V](by)).Next, i.collector)
    53  // }
    54  
    55  // FilterValue returns a stream consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
    56  func (i Iter[K, V, M]) FilterValue(predicate func(V) bool) Iter[K, V, M] {
    57  	return New(loop.Filter(i.next, filter.Value[K](predicate)).Next, i.collector)
    58  }
    59  
    60  // FiltValue returns a stream consisting of key/value pairs where the value satisfies the condition of the 'predicate' function
    61  func (i Iter[K, V, M]) FiltValue(predicate func(V) (bool, error)) Iter[K, V, M] {
    62  	return New(loop.Filt(i.next, breakFilter.Value[K](predicate)).Next, i.collector)
    63  }
    64  
    65  // // ConvertValue returns a stream that applies the 'converter' function to values of the map
    66  // func (i StreamIter[K, V, M]) ConvertValue(by func(V) V) Iter[K, V, M] {
    67  // 	return Stream(Convert(i.next, convert.Value[K](by)).Next, i.collector)
    68  // }
    69  
    70  // Filter returns a stream consisting of elements that satisfy the condition of the 'predicate' function
    71  func (i Iter[K, V, M]) Filter(predicate func(K, V) bool) Iter[K, V, M] {
    72  	return New(loop.Filter(i.next, predicate).Next, i.collector)
    73  }
    74  
    75  // Filt returns a breakable stream consisting of elements that satisfy the condition of the 'predicate' function
    76  func (i Iter[K, V, M]) Filt(predicate func(K, V) (bool, error)) Iter[K, V, M] {
    77  	return New(loop.Filt(i.next, predicate).Next, i.collector)
    78  }
    79  
    80  // // Convert returns a stream that applies the 'converter' function to the collection elements
    81  // func (i StreamIter[K, V, M]) Convert(converter func(K, V) (K, V)) Iter[K, V, M] {
    82  // 	return Stream(Convert(i.next, converter).Next, i.collector)
    83  // }
    84  
    85  // Track applies the 'tracker' function for key/value pairs. Return the c.ErrBreak to stop.
    86  func (i Iter[K, V, M]) Track(tracker func(K, V) error) error {
    87  	return breakLoop.Track(i.next, tracker)
    88  }
    89  
    90  // Reduce reduces the key/value pairs into an one pair using the 'merge' function
    91  func (i Iter[K, V, M]) Reduce(by func(K, K, V, V) (K, V, error)) (K, V, error) {
    92  	return loop.Reducee(i.next, by)
    93  }
    94  
    95  // HasAny finds the first key/value pari that satisfies the 'predicate' function condition and returns true if successful
    96  func (i Iter[K, V, M]) HasAny(predicate func(K, V) (bool, error)) (bool, error) {
    97  	next := i.next
    98  	return loop.HasAnyy(next, predicate)
    99  }
   100  
   101  // Iter creates an iterator and returns as interface
   102  func (i Iter[K, V, M]) Iter() kv.Iterator[K, V] {
   103  	return i
   104  }
   105  
   106  // Map collects the key/value pairs to a map
   107  func (i Iter[K, V, M]) Map() (M, error) {
   108  	return i.collector(i.next)
   109  }
   110  
   111  // Start is used with for loop construct like 'for i, k, v, ok, err := i.Start(); ok || err != nil ; k, v, ok, err = i.Next() { if err != nil { return err }}'
   112  func (i Iter[K, V, M]) Start() (Iter[K, V, M], K, V, bool, error) {
   113  	k, v, ok, err := i.next()
   114  	return i, k, v, ok, err
   115  }
   116  
   117  // 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
   118  type MapCollector[K comparable, V any, M map[K]V | map[K][]V] func(next func() (K, V, bool, error)) (M, error)