github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/lists/doublylinkedlist/iterator.go (about) 1 package doublylinkedlist 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 element *element[E] 13 } 14 15 // Iterator returns a stateful iterator whose values can be fetched by an index. 16 func (list *List[E]) Iterator() Iterator[E] { 17 return Iterator[E]{list: list, index: -1, element: nil} 18 } 19 20 // Next moves the iterator to the next element and returns true if there was a next element in the container. 21 // If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). 22 // If Next() was called for the first time, then it will point the iterator to the first element if it exists. 23 // Modifies the state of the iterator. 24 func (iterator *Iterator[E]) Next() bool { 25 if iterator.index < iterator.list.size { 26 iterator.index++ 27 } 28 if !iterator.list.withinRange(iterator.index) { 29 iterator.element = nil 30 return false 31 } 32 if iterator.index != 0 { 33 iterator.element = iterator.element.next 34 } else { 35 iterator.element = iterator.list.first 36 } 37 return true 38 } 39 40 // Prev moves the iterator to the previous element and returns true if there was a previous element in the container. 41 // If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value(). 42 // Modifies the state of the iterator. 43 func (iterator *Iterator[E]) Prev() bool { 44 if iterator.index >= 0 { 45 iterator.index-- 46 } 47 if !iterator.list.withinRange(iterator.index) { 48 iterator.element = nil 49 return false 50 } 51 if iterator.index == iterator.list.size-1 { 52 iterator.element = iterator.list.last 53 } else { 54 iterator.element = iterator.element.prev 55 } 56 return iterator.list.withinRange(iterator.index) 57 } 58 59 // Value returns the current element's value. 60 // Does not modify the state of the iterator. 61 func (iterator *Iterator[E]) Value() E { 62 return iterator.element.value 63 } 64 65 // Index returns the current element's index. 66 // Does not modify the state of the iterator. 67 func (iterator *Iterator[E]) Index() int { 68 return iterator.index 69 } 70 71 // Begin resets the iterator to its initial state (one-before-first) 72 // Call Next() to fetch the first element if any. 73 func (iterator *Iterator[E]) Begin() { 74 iterator.index = -1 75 iterator.element = nil 76 } 77 78 // End moves the iterator past the last element (one-past-the-end). 79 // Call Prev() to fetch the last element if any. 80 func (iterator *Iterator[E]) End() { 81 iterator.index = iterator.list.size 82 iterator.element = iterator.list.last 83 } 84 85 // First moves the iterator to the first element and returns true if there was a first element in the container. 86 // If First() returns true, then first element's index and value can be retrieved by Index() and Value(). 87 // Modifies the state of the iterator. 88 func (iterator *Iterator[E]) First() bool { 89 iterator.Begin() 90 return iterator.Next() 91 } 92 93 // Last moves the iterator to the last element and returns true if there was a last element in the container. 94 // If Last() returns true, then last element's index and value can be retrieved by Index() and Value(). 95 // Modifies the state of the iterator. 96 func (iterator *Iterator[E]) Last() bool { 97 iterator.End() 98 return iterator.Prev() 99 } 100 101 // NextTo moves the iterator to the next element from current position that satisfies the condition given by the 102 // passed function, and returns true if there was a next element in the container. 103 // If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value(). 104 // Modifies the state of the iterator. 105 func (iterator *Iterator[E]) NextTo(f func(index int, value E) bool) bool { 106 for iterator.Next() { 107 index, value := iterator.Index(), iterator.Value() 108 if f(index, value) { 109 return true 110 } 111 } 112 return false 113 } 114 115 // PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the 116 // passed function, and returns true if there was a next element in the container. 117 // If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value(). 118 // Modifies the state of the iterator. 119 func (iterator *Iterator[E]) PrevTo(f func(index int, value E) bool) bool { 120 for iterator.Prev() { 121 index, value := iterator.Index(), iterator.Value() 122 if f(index, value) { 123 return true 124 } 125 } 126 return false 127 }