github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/sets/treeset/iterator.go (about)

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