github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/lists/arraylist/iterator.go (about) 1 package arraylist 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 holding the iterator's state 9 type Iterator[E any] struct { 10 list *List[E] 11 index int 12 } 13 14 // Iterator returns a stateful iterator whose values can be fetched by an index. 15 func (l *List[E]) Iterator() Iterator[E] { 16 return Iterator[E]{list: l, 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.list.size { 25 iterator.index++ 26 } 27 return iterator.list.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.list.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 return iterator.list.elements[iterator.index] 44 } 45 46 // Index returns the current element's index. 47 // Does not modify the state of the iterator. 48 func (iterator *Iterator[E]) Index() int { 49 return iterator.index 50 } 51 52 // Begin resets the iterator to its initial state (one-before-first) 53 // Call Next() to fetch the first element if any. 54 func (iterator *Iterator[E]) Begin() { 55 iterator.index = -1 56 } 57 58 // End moves the iterator past the last element (one-past-the-end). 59 // Call Prev() to fetch the last element if any. 60 func (iterator *Iterator[E]) End() { 61 iterator.index = iterator.list.size 62 } 63 64 // First moves the iterator to the first element and returns true if there was a first element in the container. 65 // If First() returns true, then first element's index and value can be retrieved by Index() and Value(). 66 // Modifies the state of the iterator. 67 func (iterator *Iterator[E]) First() bool { 68 iterator.Begin() 69 return iterator.Next() 70 } 71 72 // Last moves the iterator to the last element and returns true if there was a last element in the container. 73 // If Last() returns true, then last element's index and value can be retrieved by Index() and Value(). 74 // Modifies the state of the iterator. 75 func (iterator *Iterator[E]) Last() bool { 76 iterator.End() 77 return iterator.Prev() 78 } 79 80 // NextTo moves the iterator to the next element from current position that satisfies the condition given by the 81 // passed function, and returns true if there was a next element in the container. 82 // If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value(). 83 // Modifies the state of the iterator. 84 func (iterator *Iterator[E]) NextTo(f func(index int, value E) bool) bool { 85 for iterator.Next() { 86 index, value := iterator.Index(), iterator.Value() 87 if f(index, value) { 88 return true 89 } 90 } 91 return false 92 } 93 94 // PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the 95 // passed function, and returns true if there was a next element in the container. 96 // If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value(). 97 // Modifies the state of the iterator. 98 func (iterator *Iterator[E]) PrevTo(f func(index int, value E) bool) bool { 99 for iterator.Prev() { 100 index, value := iterator.Index(), iterator.Value() 101 if f(index, value) { 102 return true 103 } 104 } 105 return false 106 }