github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/stacks/linkedliststack/iterator.go (about) 1 package linkedliststack 2 3 import "github.com/songzhibin97/go-baseutils/structure/containers" 4 5 // Assert Iterator implementation 6 var _ containers.IteratorWithIndex[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 // Value returns the current element's value. 31 // Does not modify the state of the iterator. 32 func (iterator *Iterator[E]) Value() E { 33 value, _ := iterator.stack.list.Get(iterator.index) // in reverse (LIFO) 34 return value 35 } 36 37 // Index returns the current element's index. 38 // Does not modify the state of the iterator. 39 func (iterator *Iterator[E]) Index() int { 40 return iterator.index 41 } 42 43 // Begin resets the iterator to its initial state (one-before-first) 44 // Call Next() to fetch the first element if any. 45 func (iterator *Iterator[E]) Begin() { 46 iterator.index = -1 47 } 48 49 // First moves the iterator to the first element and returns true if there was a first element in the container. 50 // If First() returns true, then first element's index and value can be retrieved by Index() and Value(). 51 // Modifies the state of the iterator. 52 func (iterator *Iterator[E]) First() bool { 53 iterator.Begin() 54 return iterator.Next() 55 } 56 57 // NextTo moves the iterator to the next element from current position that satisfies the condition given by the 58 // passed function, and returns true if there was a next element in the container. 59 // If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value(). 60 // Modifies the state of the iterator. 61 func (iterator *Iterator[E]) NextTo(f func(index int, value E) bool) bool { 62 for iterator.Next() { 63 index, value := iterator.Index(), iterator.Value() 64 if f(index, value) { 65 return true 66 } 67 } 68 return false 69 }