github.com/m4gshm/gollections@v0.0.10/collection/immutable/ordered/map_iter.go (about)

     1  // Package ordered provides ordered map iterator implementations
     2  package ordered
     3  
     4  import (
     5  	"github.com/m4gshm/gollections/c"
     6  	"github.com/m4gshm/gollections/kv"
     7  	"github.com/m4gshm/gollections/loop"
     8  	"github.com/m4gshm/gollections/slice"
     9  )
    10  
    11  // NewMapIter is the Iter constructor
    12  func NewMapIter[K comparable, V any](uniques map[K]V, elements slice.Iter[K]) MapIter[K, V] {
    13  	return MapIter[K, V]{elements: elements, uniques: uniques}
    14  }
    15  
    16  // MapIter is the ordered key/value pairs Iterator implementation
    17  type MapIter[K comparable, V any] struct {
    18  	elements slice.Iter[K]
    19  	uniques  map[K]V
    20  }
    21  
    22  var _ kv.Iterator[string, any] = (*MapIter[string, any])(nil)
    23  var _ kv.IterFor[int, string, *MapIter[int, string]] = (*MapIter[int, string])(nil)
    24  
    25  // Track takes key, value pairs retrieved by the iterator. Can be interrupt by returning ErrBreak
    26  func (i *MapIter[K, V]) Track(traker func(key K, value V) error) error {
    27  	return loop.Track(i.Next, traker)
    28  }
    29  
    30  // TrackEach takes all key, value pairs retrieved by the iterator
    31  func (i *MapIter[K, V]) TrackEach(traker func(key K, value V)) {
    32  	loop.TrackEach(i.Next, traker)
    33  }
    34  
    35  // Next returns the next key/value pair.
    36  // The ok result indicates whether the pair was returned by the iterator.
    37  // If ok == false, then the iteration must be completed.
    38  func (i *MapIter[K, V]) Next() (key K, val V, ok bool) {
    39  	if i != nil {
    40  		if key, ok = i.elements.Next(); ok {
    41  			val = i.uniques[key]
    42  		}
    43  	}
    44  	return key, val, ok
    45  }
    46  
    47  // Cap returns the iterator capacity
    48  func (i *MapIter[K, V]) Cap() int {
    49  	return i.elements.Cap()
    50  }
    51  
    52  // Start is used with for loop construct like 'for i, k, v, ok := i.Start(); ok; k, v, ok = i.Next() { }'
    53  func (i *MapIter[K, V]) Start() (*MapIter[K, V], K, V, bool) {
    54  	k, v, ok := i.Next()
    55  	return i, k, v, ok
    56  }
    57  
    58  // NewValIter is default ValIter constructor
    59  func NewValIter[K comparable, V any](elements []K, uniques map[K]V) ValIter[K, V] {
    60  	return ValIter[K, V]{elements: elements, uniques: uniques, current: slice.IterNoStarted}
    61  }
    62  
    63  // ValIter is the Iteratoc over Map values
    64  type ValIter[K comparable, V any] struct {
    65  	elements []K
    66  	uniques  map[K]V
    67  	current  int
    68  }
    69  
    70  var (
    71  	_ c.Iterator[any] = (*ValIter[int, any])(nil)
    72  	_ c.Sized         = (*ValIter[int, any])(nil)
    73  )
    74  
    75  var _ c.IterFor[any, *ValIter[int, any]] = (*ValIter[int, any])(nil)
    76  
    77  // For takes elements retrieved by the iterator. Can be interrupt by returning ErrBreak
    78  func (i *ValIter[K, V]) For(walker func(element V) error) error {
    79  	return loop.For(i.Next, walker)
    80  }
    81  
    82  // ForEach FlatIter all elements retrieved by the iterator
    83  func (i *ValIter[K, V]) ForEach(walker func(element V)) {
    84  	loop.ForEach(i.Next, walker)
    85  }
    86  
    87  // Next returns the next element.
    88  // The ok result indicates whether the element was returned by the iterator.
    89  // If ok == false, then the iteration must be completed.
    90  func (i *ValIter[K, V]) Next() (val V, ok bool) {
    91  	if i != nil && slice.HasNext(i.elements, i.current) {
    92  		i.current++
    93  		return i.uniques[slice.Get(i.elements, i.current)], true
    94  	}
    95  	return val, false
    96  }
    97  
    98  // Cap returns the iterator capacity
    99  func (i *ValIter[K, V]) Cap() int {
   100  	if i == nil {
   101  		return 0
   102  	}
   103  	return len(i.elements)
   104  }
   105  
   106  // Start is used with for loop construct like 'for i, val, ok := i.Start(); ok; val, ok = i.Next() { }'
   107  func (i *ValIter[K, V]) Start() (*ValIter[K, V], V, bool) {
   108  	v, ok := i.Next()
   109  	return i, v, ok
   110  }