github.com/m4gshm/gollections@v0.0.10/stream/iter.go (about) 1 // Package stream provides a stream implementation and helper functions 2 package stream 3 4 import ( 5 breakLoop "github.com/m4gshm/gollections/break/loop" 6 breakStream "github.com/m4gshm/gollections/break/stream" 7 "github.com/m4gshm/gollections/c" 8 "github.com/m4gshm/gollections/loop" 9 ) 10 11 // New instantiates a stream instance 12 func New[T any](next func() (T, bool)) Iter[T] { 13 return Iter[T]{next: next} 14 } 15 16 // Iter is the Iterator based stream implementation. 17 type Iter[T any] struct { 18 next func() (T, bool) 19 } 20 21 var ( 22 _ Stream[any] = (*Iter[any])(nil) 23 _ Stream[any] = Iter[any]{} 24 _ loop.Looper[any, Iter[any]] = (*Iter[any])(nil) 25 _ loop.Looper[any, Iter[any]] = Iter[any]{} 26 _ c.Filterable[any, Iter[any], breakStream.Iter[any]] = (*Iter[any])(nil) 27 _ c.Filterable[any, Iter[any], breakStream.Iter[any]] = Iter[any]{} 28 _ c.Iterator[any] = (*Iter[any])(nil) 29 _ c.Iterator[any] = Iter[any]{} 30 _ c.IterFor[any, Iter[any]] = Iter[any]{} 31 ) 32 33 // Next implements c.Iterator 34 func (t Iter[T]) Next() (element T, ok bool) { 35 if next := t.next; next != nil { 36 element, ok = next() 37 } 38 return element, ok 39 } 40 41 // Filter returns a stream consisting of elements that satisfy the condition of the 'predicate' function 42 func (t Iter[T]) Filter(predicate func(T) bool) Iter[T] { 43 f := loop.Filter(t.next, predicate) 44 return New(f.Next) 45 } 46 47 // Filt returns a breakable stream consisting of elements that satisfy the condition of the 'predicate' function 48 func (t Iter[T]) Filt(predicate func(T) (bool, error)) breakStream.Iter[T] { 49 f := breakLoop.Filt(breakLoop.From(t.next), predicate) 50 return breakStream.New(f.Next) 51 } 52 53 // Convert returns a stream that applies the 'converter' function to the collection elements 54 func (t Iter[T]) Convert(converter func(T) T) Iter[T] { 55 conv := loop.Convert(t.next, converter) 56 return New(conv.Next) 57 } 58 59 // Conv returns a breakable stream that applies the 'converter' function to the collection elements 60 func (t Iter[T]) Conv(converter func(T) (T, error)) breakStream.Iter[T] { 61 conv := breakLoop.Conv(breakLoop.From(t.next), converter) 62 return breakStream.New(conv.Next) 63 } 64 65 // ForEach applies the 'walker' function for every element 66 func (t Iter[T]) ForEach(walker func(T)) { 67 loop.ForEach(t.next, walker) 68 } 69 70 // For applies the 'walker' function for the elements. Return the c.ErrBreak to stop. 71 func (t Iter[T]) For(walker func(T) error) error { 72 return loop.For(t.next, walker) 73 } 74 75 // Reduce reduces the elements into an one using the 'merge' function 76 func (t Iter[T]) Reduce(by func(T, T) T) T { 77 return loop.Reduce(t.next, by) 78 } 79 80 // First returns the first element that satisfies the condition of the 'predicate' function 81 func (t Iter[T]) First(predicate func(T) bool) (T, bool) { 82 return loop.First(t.next, predicate) 83 } 84 85 // Iter creates an iterator and returns as interface 86 func (t Iter[T]) Iter() c.Iterator[T] { 87 return t 88 } 89 90 // Loop creates an iterator and returns as implementation type reference 91 func (t Iter[T]) Loop() Iter[T] { 92 return t 93 } 94 95 // Slice collects the elements to a slice 96 func (t Iter[T]) Slice() []T { 97 return loop.Slice(t.next) 98 } 99 100 // Append collects the elements retrieved by the 'next' function into the specified 'out' slice 101 func (t Iter[T]) Append(out []T) []T { 102 return loop.Append(t.next, out) 103 } 104 105 // HasAny finds the first element that satisfies the 'predicate' function condition and returns true if successful 106 func (t Iter[T]) HasAny(predicate func(T) bool) bool { 107 return loop.HasAny(t.next, predicate) 108 } 109 110 // Start is used with for loop construct like 'for i, val, ok := i.Start(); ok; val, ok = i.Next() { }' 111 func (t Iter[T]) Start() (Iter[T], T, bool) { 112 n, ok := t.next() 113 return t, n, ok 114 }