github.com/m4gshm/gollections@v0.0.13-0.20240331203319-a34a86e58a24/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/collection"
     7  	kvloop "github.com/m4gshm/gollections/kv/loop"
     8  	"github.com/m4gshm/gollections/loop"
     9  	"github.com/m4gshm/gollections/slice"
    10  )
    11  
    12  // NewMapIter is the Iter constructor
    13  func NewMapIter[K comparable, V any](uniques map[K]V, elements slice.Iter[K]) MapIter[K, V] {
    14  	return MapIter[K, V]{elements: elements, uniques: uniques}
    15  }
    16  
    17  // MapIter is the ordered key/value pairs Iterator implementation
    18  type MapIter[K comparable, V any] struct {
    19  	elements slice.Iter[K]
    20  	uniques  map[K]V
    21  }
    22  
    23  var _ collection.Iterator[string, any] = (*MapIter[string, any])(nil)
    24  
    25  // All is used to iterate through the iterator using `for ... range`. Supported since go 1.22 with GOEXPERIMENT=rangefunc enabled.
    26  func (i *MapIter[K, V]) All(consumer func(key K, value V) bool) {
    27  	kvloop.All(i.Next, consumer)
    28  }
    29  
    30  // Track takes key, value pairs retrieved by the iterator. Can be interrupt by returning Break
    31  func (i *MapIter[K, V]) Track(traker func(key K, value V) error) error {
    32  	return kvloop.Track(i.Next, traker)
    33  }
    34  
    35  // TrackEach takes all key, value pairs retrieved by the iterator
    36  func (i *MapIter[K, V]) TrackEach(traker func(key K, value V)) {
    37  	kvloop.TrackEach(i.Next, traker)
    38  }
    39  
    40  // Next returns the next key/value pair.
    41  // The ok result indicates whether the pair was returned by the iterator.
    42  // If ok == false, then the iteration must be completed.
    43  func (i *MapIter[K, V]) Next() (key K, val V, ok bool) {
    44  	if i != nil {
    45  		if key, ok = i.elements.Next(); ok {
    46  			val = i.uniques[key]
    47  		}
    48  	}
    49  	return key, val, ok
    50  }
    51  
    52  // Size returns the iterator capacity
    53  func (i *MapIter[K, V]) Size() int {
    54  	return i.elements.Size()
    55  }
    56  
    57  // NewValIter is default ValIter constructor
    58  func NewValIter[K comparable, V any](elements []K, uniques map[K]V) *ValIter[K, V] {
    59  	return &ValIter[K, V]{elements: elements, uniques: uniques, current: slice.IterNoStarted}
    60  }
    61  
    62  // ValIter is the Iteratoc over Map values
    63  type ValIter[K comparable, V any] struct {
    64  	elements []K
    65  	uniques  map[K]V
    66  	current  int
    67  }
    68  
    69  var (
    70  	_ c.Iterator[any] = (*ValIter[int, any])(nil)
    71  	_ c.Sized         = (*ValIter[int, any])(nil)
    72  )
    73  
    74  // All is used to iterate through the iterator using `for ... range`. Supported since go 1.22 with GOEXPERIMENT=rangefunc enabled.
    75  func (i *ValIter[K, V]) All(consumer func(element V) bool) {
    76  	loop.All(i.Next, consumer)
    77  }
    78  
    79  // For takes elements retrieved by the iterator. Can be interrupt by returning Break
    80  func (i *ValIter[K, V]) For(consumer func(element V) error) error {
    81  	return loop.For(i.Next, consumer)
    82  }
    83  
    84  // ForEach FlatIter all elements retrieved by the iterator
    85  func (i *ValIter[K, V]) ForEach(consumer func(element V)) {
    86  	loop.ForEach(i.Next, consumer)
    87  }
    88  
    89  // Next returns the next element.
    90  // The ok result indicates whether the element was returned by the iterator.
    91  // If ok == false, then the iteration must be completed.
    92  func (i *ValIter[K, V]) Next() (val V, ok bool) {
    93  	if i != nil && slice.HasNext(i.elements, i.current) {
    94  		i.current++
    95  		return i.uniques[slice.Get(i.elements, i.current)], true
    96  	}
    97  	return val, false
    98  }
    99  
   100  // Size returns the iterator capacity
   101  func (i *ValIter[K, V]) Size() int {
   102  	if i == nil {
   103  		return 0
   104  	}
   105  	return len(i.elements)
   106  }