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)