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

     1  package loop
     2  
     3  import (
     4  	"github.com/m4gshm/gollections/kv"
     5  	"github.com/m4gshm/gollections/loop"
     6  )
     7  
     8  // FilterIter is the KVIterator wrapper that provides filtering of key/value elements by a Predicate.
     9  type FilterIter[K, V any] struct {
    10  	next   func() (K, V, bool)
    11  	filter func(K, V) bool
    12  }
    13  
    14  var (
    15  	_ kv.Iterator[any, any] = (*FilterIter[any, any])(nil)
    16  	_ kv.Iterator[any, any] = FilterIter[any, any]{}
    17  )
    18  
    19  var _ kv.IterFor[any, any, FilterIter[any, any]] = FilterIter[any, any]{}
    20  
    21  // Track takes key, value pairs retrieved by the iterator. Can be interrupt by returning ErrBreak
    22  func (f FilterIter[K, V]) Track(traker func(key K, value V) error) error {
    23  	return loop.Track(f.Next, traker)
    24  }
    25  
    26  // TrackEach takes all key, value pairs retrieved by the iterator
    27  func (f FilterIter[K, V]) TrackEach(traker func(key K, value V)) {
    28  	loop.TrackEach(f.Next, traker)
    29  }
    30  
    31  // Next returns the next key/value pair.
    32  // The ok result indicates whether the pair was returned by the iterator.
    33  // If ok == false, then the iteration must be completed.
    34  func (f FilterIter[K, V]) Next() (key K, value V, ok bool) {
    35  	if !(f.next == nil || f.filter == nil) {
    36  		key, value, ok = nextFiltered(f.next, f.filter)
    37  	}
    38  	return key, value, ok
    39  }
    40  
    41  // Start is used with for loop construct like 'for i, k, v, ok := i.Start(); ok; k, v, ok = i.Next() { }'
    42  func (f FilterIter[K, V]) Start() (FilterIter[K, V], K, V, bool) {
    43  	return startKvIt[K, V](f)
    44  }
    45  
    46  func nextFiltered[K any, V any](next func() (K, V, bool), filter func(K, V) bool) (key K, val V, filtered bool) {
    47  	return First(next, filter)
    48  }