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 }