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 }