github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/stacks/arraystack/iterator.go (about) 1 package arraystack 2 3 import "github.com/songzhibin97/go-baseutils/structure/containers" 4 5 // Assert Iterator implementation 6 var _ containers.ReverseIteratorWithIndex[any] = (*Iterator[any])(nil) 7 8 // Iterator returns a stateful iterator whose values can be fetched by an index. 9 type Iterator[E any] struct { 10 stack *Stack[E] 11 index int 12 } 13 14 // Iterator returns a stateful iterator whose values can be fetched by an index. 15 func (stack *Stack[E]) Iterator() Iterator[E] { 16 return Iterator[E]{stack: stack, index: -1} 17 } 18 19 // Next moves the iterator to the next element and returns true if there was a next element in the container. 20 // If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). 21 // If Next() was called for the first time, then it will point the iterator to the first element if it exists. 22 // Modifies the state of the iterator. 23 func (iterator *Iterator[E]) Next() bool { 24 if iterator.index < iterator.stack.Size() { 25 iterator.index++ 26 } 27 return iterator.stack.withinRange(iterator.index) 28 } 29 30 // Prev moves the iterator to the previous element and returns true if there was a previous element in the container. 31 // If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value(). 32 // Modifies the state of the iterator. 33 func (iterator *Iterator[E]) Prev() bool { 34 if iterator.index >= 0 { 35 iterator.index-- 36 } 37 return iterator.stack.withinRange(iterator.index) 38 } 39 40 // Value returns the current element's value. 41 // Does not modify the state of the iterator. 42 func (iterator *Iterator[E]) Value() E { 43 value, _ := iterator.stack.list.Get(iterator.stack.list.Size() - iterator.index - 1) // in reverse (LIFO) 44 return value 45 } 46 47 // Index returns the current element's index. 48 // Does not modify the state of the iterator. 49 func (iterator *Iterator[E]) Index() int { 50 return iterator.index 51 } 52 53 // Begin resets the iterator to its initial state (one-before-first) 54 // Call Next() to fetch the first element if any. 55 func (iterator *Iterator[E]) Begin() { 56 iterator.index = -1 57 } 58 59 // End moves the iterator past the last element (one-past-the-end). 60 // Call Prev() to fetch the last element if any. 61 func (iterator *Iterator[E]) End() { 62 iterator.index = iterator.stack.Size() 63 } 64 65 // First moves the iterator to the first element and returns true if there was a first element in the container. 66 // If First() returns true, then first element's index and value can be retrieved by Index() and Value(). 67 // Modifies the state of the iterator. 68 func (iterator *Iterator[E]) First() bool { 69 iterator.Begin() 70 return iterator.Next() 71 } 72 73 // Last moves the iterator to the last element and returns true if there was a last element in the container. 74 // If Last() returns true, then last element's index and value can be retrieved by Index() and Value(). 75 // Modifies the state of the iterator. 76 func (iterator *Iterator[E]) Last() bool { 77 iterator.End() 78 return iterator.Prev() 79 } 80 81 // NextTo moves the iterator to the next element from current position that satisfies the condition given by the 82 // passed function, and returns true if there was a next element in the container. 83 // If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value(). 84 // Modifies the state of the iterator. 85 func (iterator *Iterator[E]) NextTo(f func(index int, value E) bool) bool { 86 for iterator.Next() { 87 index, value := iterator.Index(), iterator.Value() 88 if f(index, value) { 89 return true 90 } 91 } 92 return false 93 } 94 95 // PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the 96 // passed function, and returns true if there was a next element in the container. 97 // If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value(). 98 // Modifies the state of the iterator. 99 func (iterator *Iterator[E]) PrevTo(f func(index int, value E) bool) bool { 100 for iterator.Prev() { 101 index, value := iterator.Index(), iterator.Value() 102 if f(index, value) { 103 return true 104 } 105 } 106 return false 107 }