github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/lists/singlylinkedlist/iterator.go (about) 1 package singlylinkedlist 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 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.list.first 34 } else { 35 iterator.element = iterator.element.next 36 } 37 return true 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.element.value 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 iterator.element = nil 57 } 58 59 // First moves the iterator to the first element and returns true if there was a first element in the container. 60 // If First() returns true, then first element's index and value can be retrieved by Index() and Value(). 61 // Modifies the state of the iterator. 62 func (iterator *Iterator[E]) First() bool { 63 iterator.Begin() 64 return iterator.Next() 65 } 66 67 // NextTo moves the iterator to the next element from current position that satisfies the condition given by the 68 // passed function, and returns true if there was a next element in the container. 69 // If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value(). 70 // Modifies the state of the iterator. 71 func (iterator *Iterator[E]) NextTo(f func(index int, value E) bool) bool { 72 for iterator.Next() { 73 index, value := iterator.Index(), iterator.Value() 74 if f(index, value) { 75 return true 76 } 77 } 78 return false 79 }