Documentation
¶
Overview ¶
Package iterator provides a complete implementation of Rust's Iterator trait in Go.
This package translates the Rust Iterator trait and its methods to Go, maintaining semantic equivalence while adapting to Go's type system and idioms. It provides 60+ methods for iterator manipulation, transformation, filtering, and consumption.
Examples ¶
// Basic iteration
iter := iterator.FromSlice([]int{1, 2, 3})
for opt := iter.Next(); opt.IsSome(); opt = iter.Next() {
fmt.Println(opt.Unwrap())
}
// Method chaining
result := iterator.FromSlice([]int{1, 2, 3, 4, 5}).
Filter(func(x int) bool { return x%2 == 0 }).
Map(func(x int) int { return x * x }).
Collect() // []int{4, 16}
Index ¶
- func Cmp[T constraints.Ord](a Iterator[T], b Iterator[T]) constraints.Ordering
- func CmpBy[T any, U any](a Iterator[T], b Iterator[U], cmp func(T, U) int) constraints.Ordering
- func DefaultSizeHint[T any]() (uint, option.Option[uint])
- func Eq[T comparable](a Iterator[T], b Iterator[T]) bool
- func EqBy[T any, U any](a Iterator[T], b Iterator[U], eq func(T, U) bool) bool
- func FindMap[T any, U any](iter Iterator[T], f func(T) option.Option[U]) option.Option[U]
- func Fold[T any, B any](iter Iterator[T], init B, f func(B, T) B) B
- func Ge[T constraints.Digit](a Iterator[T], b Iterator[T]) bool
- func Gt[T constraints.Digit](a Iterator[T], b Iterator[T]) bool
- func IsSorted[T constraints.Digit](iter Iterator[T]) bool
- func IsSortedBy[T any](iter Iterator[T], compare func(T, T) bool) bool
- func IsSortedByKey[T any, K constraints.Digit](iter Iterator[T], f func(T) K) bool
- func Le[T constraints.Digit](a Iterator[T], b Iterator[T]) bool
- func Lt[T constraints.Digit](a Iterator[T], b Iterator[T]) bool
- func Max[T constraints.Ord](iter Iterator[T]) option.Option[T]
- func MaxByKey[T any, K constraints.Ord](iter Iterator[T], f func(T) K) option.Option[T]
- func Min[T constraints.Ord](iter Iterator[T]) option.Option[T]
- func MinByKey[T any, K constraints.Ord](iter Iterator[T], f func(T) K) option.Option[T]
- func Ne[T comparable](a Iterator[T], b Iterator[T]) bool
- func PartialCmp[T constraints.Digit](a Iterator[T], b Iterator[T]) option.Option[constraints.Ordering]
- func PartialCmpBy[T any, U any](a Iterator[T], b Iterator[U], ...) option.Option[constraints.Ordering]
- func Product[T constraints.Digit](iter Iterator[T]) T
- func Pull2[K any, V any](it Iterator[pair.Pair[K, V]]) (next func() (K, V, bool), stop func())
- func Rfind[T any](de DoubleEndedIterator[T], predicate func(T) bool) option.Option[T]
- func Rfold[T any, B any](de DoubleEndedIterator[T], init B, f func(B, T) B) B
- func Seq2[K any, V any](it Iterator[pair.Pair[K, V]]) iter.Seq2[K, V]
- func Sum[T constraints.Digit](iter Iterator[T]) T
- func TryFold[T any, B any](iter Iterator[T], init B, f func(B, T) result.Result[B]) result.Result[B]
- func TryForEach[T any, B any](iter Iterator[T], f func(T) result.Result[B]) result.Result[B]
- func TryRfold[T any, B any](de DoubleEndedIterator[T], init B, f func(B, T) result.Result[B]) result.Result[B]
- func Unzip[T any, U any](iter Iterator[pair.Pair[T, U]]) ([]T, []U)
- type BitSetLike
- type ChunkResult
- type DoubleEndedIterable
- type DoubleEndedIterator
- func (de DoubleEndedIterator[T]) AdvanceBackBy(n uint) result.VoidResult
- func (de DoubleEndedIterator[T]) NextBack() option.Option[T]
- func (de DoubleEndedIterator[T]) NthBack(n uint) option.Option[T]
- func (de DoubleEndedIterator[T]) Remaining() uint
- func (de DoubleEndedIterator[T]) Rfind(predicate func(T) bool) option.Option[T]
- func (de DoubleEndedIterator[T]) Rfold(init T, f func(T, T) T) T
- func (de DoubleEndedIterator[T]) TryRfold(init T, f func(T, T) result.Result[T]) result.Result[T]
- func (de DoubleEndedIterator[T]) XRfold(init any, f func(any, T) any) any
- func (de DoubleEndedIterator[T]) XTryRfold(init any, f func(any, T) result.Result[any]) result.Result[any]
- type Iterable
- type IterableCount
- type IterableSizeHint
- type Iterator
- func ArrayChunks[T any](iter Iterator[T], chunkSize uint) Iterator[[]T]
- func ChunkBy[T any](iter Iterator[T], predicate func(T, T) bool) Iterator[[]T]
- func Cloned[T any](iter Iterator[*T]) Iterator[T]
- func Empty[T any]() Iterator[T]
- func Enumerate[T any](iter Iterator[T]) Iterator[pair.Pair[uint, T]]
- func FilterMap[T any, U any](iter Iterator[T], f func(T) option.Option[U]) Iterator[U]
- func FlatMap[T any, U any](iter Iterator[T], f func(T) Iterator[U]) Iterator[U]
- func Flatten[T any](iter Iterator[Iterator[T]]) Iterator[T]
- func FromBitSet(bitset BitSetLike) Iterator[pair.Pair[int, bool]]
- func FromBitSetBytes(bytes []byte) Iterator[pair.Pair[int, bool]]
- func FromBitSetBytesOnes(bytes []byte) Iterator[int]
- func FromBitSetBytesZeros(bytes []byte) Iterator[int]
- func FromBitSetOnes(bitset BitSetLike) Iterator[int]
- func FromBitSetZeros(bitset BitSetLike) Iterator[int]
- func FromElements[T any](elems ...T) Iterator[T]
- func FromFunc[T any](f func() option.Option[T]) Iterator[T]
- func FromIterable[T any](data Iterable[T]) Iterator[T]
- func FromPull[T any](next func() (T, bool), stop func()) (Iterator[T], func())
- func FromPull2[K any, V any](next func() (K, V, bool), stop func()) (Iterator[pair.Pair[K, V]], func())
- func FromRange[T constraints.Integer](start T, end T) Iterator[T]
- func FromSeq[T any](seq iter.Seq[T]) (Iterator[T], func())
- func FromSeq2[K any, V any](seq iter.Seq2[K, V]) (Iterator[pair.Pair[K, V]], func())
- func FromSlice[T any](slice []T) Iterator[T]
- func Map[T any, U any](iter Iterator[T], f func(T) U) Iterator[U]
- func MapWhile[T any, U any](iter Iterator[T], predicate func(T) option.Option[U]) Iterator[U]
- func MapWindows[T any, U any](iter Iterator[T], windowSize uint, f func([]T) U) Iterator[U]
- func Once[T any](value T) Iterator[T]
- func OptMap[T any, U any](iter Iterator[T], f func(T) *U) Iterator[option.Option[*U]]
- func Repeat[T any](value T) Iterator[T]
- func RetMap[T any, U any](iter Iterator[T], f func(T) (U, error)) Iterator[result.Result[U]]
- func Scan[T any, U any, St any](iter Iterator[T], initialState St, f func(*St, T) option.Option[U]) Iterator[U]
- func Zip[T any, U any](a Iterator[T], b Iterator[U]) Iterator[pair.Pair[T, U]]
- func (it Iterator[T]) AdvanceBy(n uint) result.VoidResult
- func (it Iterator[T]) All(predicate func(T) bool) bool
- func (it Iterator[T]) Any(predicate func(T) bool) bool
- func (it Iterator[T]) Chain(other Iterator[T]) Iterator[T]
- func (it Iterator[T]) Collect() []T
- func (it Iterator[T]) Count() uint
- func (it Iterator[T]) Cycle() Iterator[T]
- func (it Iterator[T]) Filter(predicate func(T) bool) Iterator[T]
- func (it Iterator[T]) FilterMap(f func(T) option.Option[T]) Iterator[T]
- func (it Iterator[T]) Find(predicate func(T) bool) option.Option[T]
- func (it Iterator[T]) FindMap(f func(T) option.Option[T]) option.Option[T]
- func (it Iterator[T]) FlatMap(f func(T) Iterator[T]) Iterator[T]
- func (it Iterator[T]) Fold(init T, f func(T, T) T) T
- func (it Iterator[T]) ForEach(f func(T))
- func (it Iterator[T]) Fuse() Iterator[T]
- func (it Iterator[T]) Inspect(f func(T)) Iterator[T]
- func (it Iterator[T]) Intersperse(separator T) Iterator[T]
- func (it Iterator[T]) IntersperseWith(separator func() T) Iterator[T]
- func (it Iterator[T]) Last() option.Option[T]
- func (it Iterator[T]) Map(f func(T) T) Iterator[T]
- func (it Iterator[T]) MapWhile(predicate func(T) option.Option[T]) Iterator[T]
- func (it Iterator[T]) MapWindows(windowSize uint, f func([]T) T) Iterator[T]
- func (it Iterator[T]) MaxBy(compare func(T, T) int) option.Option[T]
- func (it Iterator[T]) MinBy(compare func(T, T) int) option.Option[T]
- func (it Iterator[T]) MustToDoubleEnded() DoubleEndedIterator[T]
- func (it Iterator[T]) Next() option.Option[T]
- func (it Iterator[T]) NextChunk(n uint) ChunkResult[[]T]
- func (it Iterator[T]) Nth(n uint) option.Option[T]
- func (it Iterator[T]) Partition(f func(T) bool) (truePart []T, falsePart []T)
- func (it Iterator[T]) Peekable() PeekableIterator[T]
- func (it Iterator[T]) Position(predicate func(T) bool) option.Option[uint]
- func (it Iterator[T]) Pull() (next func() (T, bool), stop func())
- func (it Iterator[T]) Pull2() (next func() (uint, T, bool), stop func())
- func (it Iterator[T]) Reduce(f func(T, T) T) option.Option[T]
- func (it Iterator[T]) Scan(initialState T, f func(*T, T) option.Option[T]) Iterator[T]
- func (it Iterator[T]) Seq() iter.Seq[T]
- func (it Iterator[T]) Seq2() iter.Seq2[uint, T]
- func (it Iterator[T]) SizeHint() (uint, option.Option[uint])
- func (it Iterator[T]) Skip(n uint) Iterator[T]
- func (it Iterator[T]) SkipWhile(predicate func(T) bool) Iterator[T]
- func (it Iterator[T]) StepBy(step uint) Iterator[T]
- func (it Iterator[T]) Take(n uint) Iterator[T]
- func (it Iterator[T]) TakeWhile(predicate func(T) bool) Iterator[T]
- func (it Iterator[T]) TryFind(f func(T) result.Result[bool]) result.Result[option.Option[T]]
- func (it Iterator[T]) TryFold(init T, f func(T, T) result.Result[T]) result.Result[T]
- func (it Iterator[T]) TryForEach(f func(T) result.Result[T]) result.Result[T]
- func (it Iterator[T]) TryReduce(f func(T, T) result.Result[T]) result.Result[option.Option[T]]
- func (it Iterator[T]) TryToDoubleEnded() option.Option[DoubleEndedIterator[T]]
- func (it Iterator[T]) XFilterMap(f func(T) option.Option[any]) Iterator[any]
- func (it Iterator[T]) XFindMap(f func(T) option.Option[any]) option.Option[any]
- func (it Iterator[T]) XFlatMap(f func(T) Iterator[any]) Iterator[any]
- func (it Iterator[T]) XFold(init any, f func(any, T) any) any
- func (it Iterator[T]) XMap(f func(T) any) Iterator[any]
- func (it Iterator[T]) XMapWhile(predicate func(T) option.Option[any]) Iterator[any]
- func (it Iterator[T]) XMapWindows(windowSize uint, f func([]T) any) Iterator[any]
- func (it Iterator[T]) XScan(initialState any, f func(*any, T) option.Option[any]) Iterator[any]
- func (it Iterator[T]) XTryFold(init any, f func(any, T) result.Result[any]) result.Result[any]
- func (it Iterator[T]) XTryForEach(f func(T) result.Result[any]) result.Result[any]
- type PeekableIterator
- type SizeIterable
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Cmp ¶
func Cmp[T constraints.Ord](a Iterator[T], b Iterator[T]) constraints.Ordering
Cmp lexicographically compares the elements of this Iterator with those of another.
Examples ¶
assert.Equal(t, constraints.Less(), Cmp(FromSlice([]int{1}), FromSlice([]int{1})))
assert.Equal(t, constraints.Less(), Cmp(FromSlice([]int{1}), FromSlice([]int{1, 2})))
assert.Equal(t, constraints.Greater(), Cmp(FromSlice([]int{1, 2}), FromSlice([]int{1})))
func CmpBy ¶
CmpBy lexicographically compares the elements of this Iterator with those of another with respect to the specified comparison function.
Examples ¶
var xs = []int{1, 2, 3, 4}
var ys = []int{1, 4, 9, 16}
var result = CmpBy(FromSlice(xs), FromSlice(ys), func(x, y int) int {
if x*x < y {
return -1
}
if x*x > y {
return 1
}
return 0
})
assert.Equal(t, constraints.Equal(), result)
func DefaultSizeHint ¶
DefaultSizeHint provides a default implementation of SizeHint that returns (0, None). This can be used by iterator implementations that don't have size information.
func Eq ¶
func Eq[T comparable](a Iterator[T], b Iterator[T]) bool
Eq determines if the elements of this Iterator are equal to those of another.
Examples ¶
assert.True(t, Eq(FromSlice([]int{1}), FromSlice([]int{1})))
assert.False(t, Eq(FromSlice([]int{1}), FromSlice([]int{1, 2})))
func EqBy ¶
EqBy determines if the elements of this Iterator are equal to those of another with respect to the specified equality function.
Examples ¶
var xs = []int{1, 2, 3, 4}
var ys = []int{1, 4, 9, 16}
assert.True(t, EqBy(FromSlice(xs), FromSlice(ys), func(x, y int) bool { return x*x == y }))
func FindMap ¶
FindMap applies function to the elements of iterator and returns the first non-none result.
FindMap(f) is equivalent to FilterMap(iter, f).Next().
Examples ¶
var a = []string{"lol", "NaN", "2", "5"}
var firstNumber = FindMap(FromSlice(a), func(s string) option.Option[int] {
if v, err := strconv.Atoi(s); err == nil {
return option.Some(v)
}
return option.None[int]()
})
assert.Equal(t, option.Some(2), firstNumber)
func Fold ¶
Fold folds every element into an accumulator by applying an operation, returning the final result.
Fold() takes two arguments: an initial value, and a closure with two arguments: an 'accumulator', and an element. The closure returns the value that the accumulator should have for the next iteration.
The initial value is the value the accumulator will have on the first call.
After applying this closure to every element of the iterator, Fold() returns the accumulator.
This operation is sometimes called 'reduce' or 'inject'.
Folding is useful whenever you have a collection of something, and want to produce a single value from it.
Note: Fold(), and similar methods that traverse the entire iterator, might not terminate for infinite iterators, even on traits for which a result is determinable in finite time.
Note: Reduce() can be used to use the first element as the initial value, if the accumulator type and item type is the same.
Note: Fold() combines elements in a *left-associative* fashion. For associative operators like +, the order the elements are combined in is not important, but for non-associative operators like - the order will affect the final result.
Examples ¶
Basic usage:
var a = []int{1, 2, 3}
// the sum of all of the elements of the array
var sum = Fold(FromSlice(a), 0, func(acc int, x int) int { return acc + x })
assert.Equal(t, 6, sum)
Let's walk through each step of the iteration here:
| element | acc | x | result | |---------|-----|---|--------| | | 0 | | | | 1 | 0 | 1 | 1 | | 2 | 1 | 2 | 3 | | 3 | 3 | 3 | 6 |
And so, our final result, 6.
func Ge ¶
func Ge[T constraints.Digit](a Iterator[T], b Iterator[T]) bool
Ge determines if the elements of this Iterator are lexicographically greater than or equal to those of another.
Examples ¶
assert.True(t, Ge(FromSlice([]int{1}), FromSlice([]int{1})))
assert.False(t, Ge(FromSlice([]int{1}), FromSlice([]int{1, 2})))
assert.True(t, Ge(FromSlice([]int{1, 2}), FromSlice([]int{1})))
func Gt ¶
func Gt[T constraints.Digit](a Iterator[T], b Iterator[T]) bool
Gt determines if the elements of this Iterator are lexicographically greater than those of another.
Examples ¶
assert.False(t, Gt(FromSlice([]int{1}), FromSlice([]int{1})))
assert.False(t, Gt(FromSlice([]int{1}), FromSlice([]int{1, 2})))
assert.True(t, Gt(FromSlice([]int{1, 2}), FromSlice([]int{1})))
func IsSorted ¶
func IsSorted[T constraints.Digit](iter Iterator[T]) bool
IsSorted checks if the elements of this iterator are sorted.
That is, for each element a and its following element b, a <= b must hold. If the iterator yields exactly zero or one element, true is returned.
Note that if T is only PartialOrd, but not Ord, the above definition implies that this function returns false if any two consecutive items are not comparable.
Examples ¶
assert.True(t, IsSorted(FromSlice([]int{1, 2, 2, 9})))
assert.False(t, IsSorted(FromSlice([]int{1, 3, 2, 4})))
assert.True(t, IsSorted(FromSlice([]int{0})))
assert.True(t, IsSorted(Empty[int]()))
func IsSortedBy ¶
IsSortedBy checks if the elements of this iterator are sorted using the given comparator function.
Instead of using PartialOrd::partial_cmp, this function uses the given compare function to determine whether two elements are to be considered in sorted order.
Examples ¶
assert.True(t, IsSortedBy(FromSlice([]int{1, 2, 2, 9}), func(a, b int) bool { return a <= b }))
assert.False(t, IsSortedBy(FromSlice([]int{1, 2, 2, 9}), func(a, b int) bool { return a < b }))
func IsSortedByKey ¶
func IsSortedByKey[T any, K constraints.Digit](iter Iterator[T], f func(T) K) bool
IsSortedByKey checks if the elements of this iterator are sorted using the given key extraction function.
Instead of comparing the iterator's elements directly, this function compares the keys of the elements, as determined by f. Apart from that, it's equivalent to IsSorted; see its documentation for more information.
Examples ¶
assert.True(t, IsSortedByKey(FromSlice([]string{"c", "bb", "aaa"}), func(s string) int { return len(s) }))
assert.False(t, IsSortedByKey(FromSlice([]int{-2, -1, 0, 3}), func(n int) int {
if n < 0 {
return -n
}
return n
}))
func Le ¶
func Le[T constraints.Digit](a Iterator[T], b Iterator[T]) bool
Le determines if the elements of this Iterator are lexicographically less or equal to those of another.
Examples ¶
assert.True(t, Le(FromSlice([]int{1}), FromSlice([]int{1})))
assert.True(t, Le(FromSlice([]int{1}), FromSlice([]int{1, 2})))
assert.False(t, Le(FromSlice([]int{1, 2}), FromSlice([]int{1})))
func Lt ¶
func Lt[T constraints.Digit](a Iterator[T], b Iterator[T]) bool
Lt determines if the elements of this Iterator are lexicographically less than those of another.
Examples ¶
assert.False(t, Lt(FromSlice([]int{1}), FromSlice([]int{1})))
assert.True(t, Lt(FromSlice([]int{1}), FromSlice([]int{1, 2})))
assert.False(t, Lt(FromSlice([]int{1, 2}), FromSlice([]int{1})))
func Max ¶
func Max[T constraints.Ord](iter Iterator[T]) option.Option[T]
Max returns the maximum element of an iterator.
If several elements are equally maximum, the last element is returned. If the iterator is empty, option.None[T]() is returned.
Note that f32/f64 doesn't implement Ord due to NaN being incomparable. You can work around this by using Reduce:
var max = Reduce(FromSlice([]float32{2.4, float32(math.NaN()), 1.3}), func(a, b float32) float32 {
if a > b {
return a
}
return b
})
Examples ¶
var a = []int{1, 2, 3}
var b = []int{}
assert.Equal(t, option.Some(3), Max(FromSlice(a)))
assert.Equal(t, option.None[int](), Max(FromSlice(b)))
func MaxByKey ¶
MaxByKey returns the element that gives the maximum value from the specified function.
If several elements are equally maximum, the last element is returned. If the iterator is empty, option.None[T]() is returned.
Examples ¶
var a = []int{-3, 0, 1, 5, -10}
var max = MaxByKey(FromSlice(a), func(x int) int {
if x < 0 {
return -x
}
return x
})
assert.Equal(t, option.Some(-10), max)
func Min ¶
func Min[T constraints.Ord](iter Iterator[T]) option.Option[T]
Min returns the minimum element of an iterator.
If several elements are equally minimum, the first element is returned. If the iterator is empty, option.None[T]() is returned.
Note that f32/f64 doesn't implement Ord due to NaN being incomparable. You can work around this by using Reduce:
var min = Reduce(FromSlice([]float32{2.4, float32(math.NaN()), 1.3}), func(a, b float32) float32 {
if a < b {
return a
}
return b
})
Examples ¶
var a = []int{1, 2, 3}
var b = []int{}
assert.Equal(t, option.Some(1), Min(FromSlice(a)))
assert.Equal(t, option.None[int](), Min(FromSlice(b)))
func MinByKey ¶
MinByKey returns the element that gives the minimum value from the specified function.
If several elements are equally minimum, the first element is returned. If the iterator is empty, option.None[T]() is returned.
Examples ¶
var a = []int{-3, 0, 1, 5, -10}
var min = MinByKey(FromSlice(a), func(x int) int {
if x < 0 {
return -x
}
return x
})
assert.Equal(t, option.Some(0), min)
func Ne ¶
func Ne[T comparable](a Iterator[T], b Iterator[T]) bool
Ne determines if the elements of this Iterator are not equal to those of another.
Examples ¶
assert.False(t, Ne(FromSlice([]int{1}), FromSlice([]int{1})))
assert.True(t, Ne(FromSlice([]int{1}), FromSlice([]int{1, 2})))
func PartialCmp ¶
func PartialCmp[T constraints.Digit](a Iterator[T], b Iterator[T]) option.Option[constraints.Ordering]
PartialCmp lexicographically compares the PartialOrd elements of this Iterator with those of another. The comparison works like short-circuit evaluation, returning a result without comparing the remaining elements. As soon as an order can be determined, the evaluation stops and a result is returned.
Examples ¶
var result = PartialCmp(FromSlice([]float64{1.0}), FromSlice([]float64{1.0}))
assert.Equal(t, option.Some(constraints.Equal()), result)
var result2 = PartialCmp(FromSlice([]float64{1.0}), FromSlice([]float64{1.0, 2.0}))
assert.Equal(t, option.Some(constraints.Less()), result2)
// For floating-point numbers, NaN does not have a total order
var nan = []float64{0.0 / 0.0}
var result3 = PartialCmp(FromSlice(nan), FromSlice([]float64{1.0}))
assert.Equal(t, option.None[constraints.Ordering](), result3)
func PartialCmpBy ¶
func PartialCmpBy[T any, U any](a Iterator[T], b Iterator[U], partialCmp func(T, U) option.Option[constraints.Ordering]) option.Option[constraints.Ordering]
PartialCmpBy lexicographically compares the elements of this Iterator with those of another with respect to the specified comparison function.
Examples ¶
var xs = []float64{1.0, 2.0, 3.0, 4.0}
var ys = []float64{1.0, 4.0, 9.0, 16.0}
var result = PartialCmpBy(FromSlice(xs), FromSlice(ys), func(x, y float64) option.Option[constraints.Ordering] {
if x*x < y {
return option.Some(constraints.Less())
}
if x*x > y {
return option.Some(constraints.Greater())
}
return option.Some(constraints.Equal())
})
assert.Equal(t, option.Some(constraints.Equal()), result)
func Product ¶
func Product[T constraints.Digit](iter Iterator[T]) T
Product iterates over the entire iterator, multiplying all the elements
An empty iterator returns the one value of the type.
Panics ¶
When calling Product() and a primitive integer type is being returned, method will panic if the computation overflows and overflow checks are enabled.
Examples ¶
var factorial = func(n int) int {
return Product(FromRange(1, n+1))
}
assert.Equal(t, 1, factorial(0))
assert.Equal(t, 1, factorial(1))
assert.Equal(t, 120, factorial(5))
func Pull2 ¶
Pull2 converts the Iterator[pair.Pair[K, V]] to a pull-style iterator using Go's standard iterator.Pull2. This returns two functions: next (to pull key-value pairs) and stop (to stop iteration). The caller should defer stop() to ensure proper cleanup.
Examples ¶
iter1 := FromSlice([]int{1, 2, 3})
iter2 := FromSlice([]string{"a", "b", "c"})
zipped := Zip(iter1, iter2)
next, stop := Pull2(zipped)
defer stop()
// Pull key-value pairs manually
for {
k, v, ok := next()
if !ok {
break
}
fmt.Println(k, v)
}
func Rfind ¶
func Rfind[T any](de DoubleEndedIterator[T], predicate func(T) bool) option.Option[T]
Rfind searches for an element of an iterator from the back that satisfies a predicate (function version).
Examples ¶
var a = []int{1, 2, 3}
var deIter = FromSlice(a).MustToDoubleEnded()
assert.Equal(t, option.Some(2), Rfind(deIter, func(x int) bool { return x == 2 }))
func Rfold ¶
func Rfold[T any, B any](de DoubleEndedIterator[T], init B, f func(B, T) B) B
Rfold folds every element into an accumulator by applying an operation, starting from the back (generic version).
Examples ¶
var a = []int{1, 2, 3}
var deIter = FromSlice(a).MustToDoubleEnded()
var sum = Rfold(deIter, 0, func(acc int, x int) int { return acc + x })
assert.Equal(t, 6, sum)
func Seq2 ¶
Seq2 converts the Iterator[pair.Pair[K, V]] to Go's standard iterator.Seq2[K, V]. This allows using gust pair iterators with Go's built-in key-value iteration support.
Examples ¶
// Convert Zip iterator to Go Seq2
iter1 := FromSlice([]int{1, 2, 3})
iter2 := FromSlice([]string{"a", "b", "c"})
zipped := Zip(iter1, iter2)
for k, v := range Seq2(zipped) {
fmt.Println(k, v) // prints 1 a, 2 b, 3 c
}
// Works with Go's standard library functions
enumerated := Enumerate(FromSlice([]string{"a", "b", "c"}))
for idx, val := range Seq2(enumerated) {
fmt.Println(idx, val) // prints 0 a, 1 b, 2 c
}
func Sum ¶
func Sum[T constraints.Digit](iter Iterator[T]) T
Sum sums the elements of an iterator.
Takes each element, adds them together, and returns the result.
An empty iterator returns the *additive identity* ("zero") of the type, which is 0 for integers and -0.0 for floats.
Panics ¶
When calling Sum() and a primitive integer type is being returned, this method will panic if the computation overflows and overflow checks are enabled.
Examples ¶
var a = []int{1, 2, 3}
var sum = Sum(FromSlice(a))
assert.Equal(t, 6, sum)
var b = []float64{}
var sumFloat = Sum(FromSlice(b))
assert.Equal(t, -0.0, sumFloat)
func TryFold ¶
func TryFold[T any, B any](iter Iterator[T], init B, f func(B, T) result.Result[B]) result.Result[B]
TryFold is an iterator method that applies a function as long as it returns successfully, producing a single, final value.
TryFold() takes two arguments: an initial value, and a closure with two arguments: an 'accumulator', and an element. The closure either returns successfully, with the value that the accumulator should have for the next iteration, or it returns failure, with an error value that is propagated back to the caller immediately (short-circuiting).
The initial value is the value the accumulator will have on the first call. If applying the closure succeeded against every element of the iterator, TryFold() returns the final accumulator as success.
Folding is useful whenever you have a collection of something, and want to produce a single value from it.
Examples ¶
Basic usage:
var a = []int{1, 2, 3}
// the checked sum of all of the elements of the array
var sum = TryFold(FromSlice(a), 0, func(acc int, x int) result.Result[int] {
// Simulate checked addition
if acc > 100 {
return result.TryErr[int](errors.New("overflow"))
}
return result.Ok(acc + x)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap())
Short-circuiting:
var a = []int{10, 20, 30, 100, 40, 50}
var iter = FromSlice(a)
// This sum overflows when adding the 100 element
var sum = TryFold(iter, 0, func(acc int, x int) result.Result[int] {
if acc+x > 50 {
return result.TryErr[int](errors.New("overflow"))
}
return result.Ok(acc + x)
})
assert.True(t, sum.IsErr())
func TryForEach ¶
TryForEach is an iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error.
This can also be thought of as the fallible form of ForEach() or as the stateless version of TryFold().
Examples ¶
var data = []string{"no_tea.txt", "stale_bread.json", "torrential_rain.png"}
var res = TryForEach(FromSlice(data), func(x string) result.Result[any] {
fmt.Println(x)
return result.Ok[any](nil)
})
assert.True(t, res.IsOk())
func TryRfold ¶
func TryRfold[T any, B any](de DoubleEndedIterator[T], init B, f func(B, T) result.Result[B]) result.Result[B]
TryRfold is the reverse version of TryFold: it takes elements starting from the back of the iterator (generic version).
Examples ¶
var a = []string{"1", "2", "3"}
var deIter = FromSlice(a).MustToDoubleEnded()
var sum = TryRfold(deIter, 0, func(acc int, s string) result.Result[int] {
if v, err := strconv.Atoi(s); err == nil {
return result.Ok(acc + v)
}
return result.TryErr[int](err)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap())
func Unzip ¶
Unzip converts an iterator of pairs into a pair of containers.
Unzip() consumes an entire iterator of pairs, producing two collections: one from the left elements of the pairs, and one from the right elements.
This function is, in some sense, the opposite of Zip.
Examples ¶
var a = []pair.Pair[int, string]{
{A: 1, B: "a"},
{A: 2, B: "b"},
{A: 3, B: "c"},
}
var (left, right) = Unzip(FromSlice(a))
assert.Equal(t, []int{1, 2, 3}, left)
assert.Equal(t, []string{"a", "b", "c"}, right)
Types ¶
type BitSetLike ¶
type BitSetLike interface {
// Size returns the number of bits in the bit set.
Size() int
// Get returns the value of the bit at the specified offset.
//
// Returns:
// - true if the bit at offset is set to 1
// - false if the bit at offset is set to 0
// - false if offset is out of range (offset < 0 or offset >= Size())
Get(offset int) bool
}
BitSetLike is an interface for bit set implementations. This allows FromBitSet to work with any bit set implementation without depending on a specific package.
type ChunkResult ¶
type ChunkResult[T any] struct { // contains filtered or unexported fields }
ChunkResult represents a success (T) or failure (T) for NextChunk. This is used when the error type is the same as the success type (e.g., []T).
func (ChunkResult[T]) IsErr ¶
func (r ChunkResult[T]) IsErr() bool
IsErr returns true if the result is an error.
func (ChunkResult[T]) IsOk ¶
func (r ChunkResult[T]) IsOk() bool
IsOk returns true if the result is ok.
func (ChunkResult[T]) Unwrap ¶
func (r ChunkResult[T]) Unwrap() T
Unwrap returns the contained T value.
func (ChunkResult[T]) UnwrapErr ¶
func (r ChunkResult[T]) UnwrapErr() T
UnwrapErr returns the contained error T value.
type DoubleEndedIterable ¶
type DoubleEndedIterable[T any] interface { Iterable[T] SizeIterable[T] // NextBack returns the next value from the back of the sequence. // Returns Some(value) if there is a next value, None otherwise. NextBack() option.Option[T] }
DoubleEndedIterable represents an iterable that can be iterated from both ends.
type DoubleEndedIterator ¶
type DoubleEndedIterator[T any] struct { Iterator[T] // Embed Iterator to inherit all its methods // contains filtered or unexported fields }
DoubleEndedIterator is the main double-ended iterator type that provides method chaining. It embeds Iterator[T] to inherit all Iterator methods, and adds double-ended specific methods. This enables Rust-like method chaining: deIter.Filter(...).NextBack().Rfold(...)
DoubleEndedIterator implements gust.Iterable[T] and gust.IterableSizeHint, so it can be used anywhere these interfaces are expected. It also inherits all Iterator[T] methods.
Examples ¶
Basic usage:
var numbers = []int{1, 2, 3, 4, 5, 6}
var deIter = FromSlice(numbers).MustToDoubleEnded()
import "github.com/andeya/gust/option"
assert.Equal(t, option.Some(1), deIter.Next())
assert.Equal(t, option.Some(6), deIter.NextBack())
assert.Equal(t, option.Some(5), deIter.NextBack())
assert.Equal(t, option.Some(2), deIter.Next())
assert.Equal(t, option.Some(3), deIter.Next())
assert.Equal(t, option.Some(4), deIter.Next())
assert.Equal(t, option.None[int](), deIter.Next())
assert.Equal(t, option.None[int](), deIter.NextBack())
// Can use all Iterator methods:
var filtered = deIter.Filter(func(x int) bool { return x > 2 })
var collected = filtered.Collect()
func (DoubleEndedIterator[T]) AdvanceBackBy ¶
func (de DoubleEndedIterator[T]) AdvanceBackBy(n uint) result.VoidResult
AdvanceBackBy advances the iterator from the back by n elements.
AdvanceBackBy is the reverse version of AdvanceBy. This method will eagerly skip n elements starting from the back by calling NextBack up to n times until None is encountered.
AdvanceBackBy(n) will return Ok[Void](nil) if the iterator successfully advances by n elements, or Err[Void](k) with value k if None is encountered, where k is remaining number of steps that could not be advanced because the iterator ran out. If iter is empty and n is non-zero, then this returns Err[Void](n). Otherwise, k is always less than n.
Calling AdvanceBackBy(0) can do meaningful work.
Examples ¶
var a = []int{3, 4, 5, 6}
var deIter = FromSlice(a).MustToDoubleEnded()
assert.True(t, deIter.AdvanceBackBy(2).IsOk())
assert.Equal(t, option.Some(4), deIter.NextBack())
assert.True(t, deIter.AdvanceBackBy(0).IsOk())
assert.True(t, deIter.AdvanceBackBy(100).IsErr())
func (DoubleEndedIterator[T]) NextBack ¶
func (de DoubleEndedIterator[T]) NextBack() option.Option[T]
NextBack removes and returns an element from the end of the iterator.
Returns None when there are no more elements.
Examples ¶
var numbers = []int{1, 2, 3, 4, 5, 6}
var deIter = FromSlice(numbers).MustToDoubleEnded()
assert.Equal(t, option.Some(6), deIter.NextBack())
assert.Equal(t, option.Some(5), deIter.NextBack())
assert.Equal(t, option.Some(4), deIter.NextBack())
assert.Equal(t, option.Some(3), deIter.NextBack())
assert.Equal(t, option.Some(2), deIter.NextBack())
assert.Equal(t, option.Some(1), deIter.NextBack())
assert.Equal(t, option.None[int](), deIter.NextBack())
func (DoubleEndedIterator[T]) NthBack ¶
func (de DoubleEndedIterator[T]) NthBack(n uint) option.Option[T]
NthBack returns the nth element from the end of the iterator.
This is essentially the reversed version of Nth(). Although like most indexing operations, the count starts from zero, so NthBack(0) returns the first value from the end, NthBack(1) the second, and so on.
Note that all elements between the end and the returned element will be consumed, including the returned element. This also means that calling NthBack(0) multiple times on the same iterator will return different elements.
NthBack() will return None if n is greater than or equal to the length of the iterator.
Examples ¶
var a = []int{1, 2, 3}
var deIter = FromSlice(a).MustToDoubleEnded()
assert.Equal(t, option.Some(1), deIter.NthBack(2))
assert.Equal(t, option.Some(2), deIter.NthBack(1))
assert.Equal(t, option.Some(3), deIter.NthBack(0))
assert.Equal(t, option.None[int](), deIter.NthBack(10))
func (DoubleEndedIterator[T]) Remaining ¶
func (de DoubleEndedIterator[T]) Remaining() uint
Remaining returns the number of elements remaining in the iterator.
Examples ¶
var numbers = []int{1, 2, 3, 4, 5, 6} var deIter = FromSlice(numbers).MustToDoubleEnded() assert.Equal(t, uint(6), deIter.Remaining()) deIter.Next() assert.Equal(t, uint(5), deIter.Remaining()) deIter.NextBack() assert.Equal(t, uint(4), deIter.Remaining()) deIter.NextBack() assert.Equal(t, uint(3), deIter.Remaining()) deIter.NextBack() assert.Equal(t, uint(2), deIter.Remaining()) deIter.NextBack() assert.Equal(t, uint(1), deIter.Remaining()) deIter.NextBack() assert.Equal(t, uint(0), deIter.Remaining()) deIter.NextBack() assert.Equal(t, uint(0), deIter.Remaining())
func (DoubleEndedIterator[T]) Rfind ¶
func (de DoubleEndedIterator[T]) Rfind(predicate func(T) bool) option.Option[T]
Rfind searches for an element of an iterator from the back that satisfies a predicate.
Rfind() takes a closure that returns true or false. It applies this closure to each element of the iterator, starting at the end, and if any of them return true, then Rfind() returns Some(element). If they all return false, it returns None.
Rfind() is short-circuiting; in other words, it will stop processing as soon as the closure returns true.
Examples ¶
var a = []int{1, 2, 3}
var deIter = FromSlice(a).MustToDoubleEnded()
assert.Equal(t, option.Some(2), deIter.Rfind(func(x int) bool { return x == 2 }))
var b = []int{1, 2, 3}
var deIter2 = FromSlice(b).MustToDoubleEnded()
assert.Equal(t, option.None[int](), deIter2.Rfind(func(x int) bool { return x == 5 }))
func (DoubleEndedIterator[T]) Rfold ¶
func (de DoubleEndedIterator[T]) Rfold(init T, f func(T, T) T) T
Rfold folds every element into an accumulator by applying an operation, starting from the back.
This is the reverse version of Fold(): it takes elements starting from the back of the iterator.
Rfold() takes two arguments: an initial value, and a closure with two arguments: an 'accumulator', and an element. The closure returns the value that the accumulator should have for the next iteration.
The initial value is the value the accumulator will have on the first call.
After applying this closure to every element of the iterator, Rfold() returns the accumulator.
Note: Rfold() combines elements in a *right-associative* fashion. For associative operators like +, the order the elements are combined in is not important, but for non-associative operators like - the order will affect the final result.
Examples ¶
var a = []int{1, 2, 3}
var deIter = FromSlice(a).MustToDoubleEnded()
var sum = deIter.Rfold(0, func(acc int, x int) int { return acc + x })
assert.Equal(t, 6, sum)
func (DoubleEndedIterator[T]) TryRfold ¶
func (de DoubleEndedIterator[T]) TryRfold(init T, f func(T, T) result.Result[T]) result.Result[T]
TryRfold is the reverse version of TryFold: it takes elements starting from the back of the iterator.
Examples ¶
var a = []string{"1", "2", "3"}
var deIter = FromSlice(a).MustToDoubleEnded()
var sum = deIter.TryRfold(0, func(acc int, s string) result.Result[int] {
if v, err := strconv.Atoi(s); err == nil {
return result.Ok(acc + v)
}
return result.TryErr[int](err)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap())
func (DoubleEndedIterator[T]) XRfold ¶
func (de DoubleEndedIterator[T]) XRfold(init any, f func(any, T) any) any
XRfold folds every element into an accumulator by applying an operation, starting from the back (any version).
This is the reverse version of Fold(): it takes elements starting from the back of the iterator.
Examples ¶
var a = []int{1, 2, 3}
var deIter = FromSlice(a).MustToDoubleEnded()
var deIter = iterator.MustToDoubleEnded()
var sum = deIter.XRfold(0, func(acc any, x int) any { return acc.(int) + x })
assert.Equal(t, 6, sum)
func (DoubleEndedIterator[T]) XTryRfold ¶
func (de DoubleEndedIterator[T]) XTryRfold(init any, f func(any, T) result.Result[any]) result.Result[any]
XTryRfold is the reverse version of TryFold: it takes elements starting from the back of the iterator (any version).
Examples ¶
var a = []string{"1", "2", "3"}
var deIter = FromSlice(a).MustToDoubleEnded()
var sum = deIter.XTryRfold(0, func(acc any, s string) result.Result[any] {
if v, err := strconv.Atoi(s); err == nil {
return result.Ok(any(acc.(int) + v))
}
return result.TryErr[any](err)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap().(int))
type Iterable ¶
type Iterable[T any] interface { // Next returns the next value in the sequence. // Returns Some(value) if there is a next value, None otherwise. Next() option.Option[T] // SizeHint returns a hint about the remaining size of the sequence. // Returns (lower_bound, Some(upper_bound)) if the size is known, // or (lower_bound, None) if the upper bound is unknown. SizeHint() (uint, option.Option[uint]) }
Iterable represents a sequence of values that can be iterated over.
type IterableCount ¶
type IterableCount interface {
// Count returns the total number of elements.
Count() uint
}
IterableCount represents an iterable that can count its elements.
type IterableSizeHint ¶
type IterableSizeHint interface {
// SizeHint returns a hint about the remaining size of the sequence.
// Returns (lower_bound, Some(upper_bound)) if the size is known,
// or (lower_bound, None) if the upper bound is unknown.
SizeHint() (uint, option.Option[uint])
}
IterableSizeHint represents an iterable that can provide size hints.
type Iterator ¶
type Iterator[T any] struct { // contains filtered or unexported fields }
Iterator is the main iterator type that provides method chaining. It wraps an Iterable[T] interface and provides all adapter methods as struct methods, enabling Rust-like method chaining: iterator.Map(...).Filter(...).Collect()
Iterator implements gust.Iterable[T] and gust.IterableSizeHint, so it can be used anywhere these interfaces are expected.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4, 5})
var result = iterator.Filter(func(x int) bool { return x > 2 }).
Take(2).
Collect()
func ArrayChunks ¶
ArrayChunks creates an iterator that yields chunks of a given size.
Panics ¶
Panics if chunk_size is 0.
Examples ¶
var iter = ArrayChunks(FromSlice([]int{1, 2, 3, 4, 5}), 2)
chunk1 := iterator.Next()
assert.True(t, chunk1.IsSome())
assert.Equal(t, []int{1, 2}, chunk1.Unwrap())
chunk2 := iterator.Next()
assert.True(t, chunk2.IsSome())
assert.Equal(t, []int{3, 4}, chunk2.Unwrap())
chunk3 := iterator.Next()
assert.True(t, chunk3.IsSome())
assert.Equal(t, []int{5}, chunk3.Unwrap()) // Last partial chunk
func ChunkBy ¶
ChunkBy creates an iterator that groups consecutive elements that are equal according to the predicate function.
The predicate function receives two consecutive elements and should return true if they should be in the same group.
Examples ¶
var iter = ChunkBy(FromSlice([]int{1, 1, 2, 2, 2, 3, 3}), func(a, b int) bool { return a == b })
chunk1 := iterator.Next()
assert.True(t, chunk1.IsSome())
assert.Equal(t, []int{1, 1}, chunk1.Unwrap())
chunk2 := iterator.Next()
assert.True(t, chunk2.IsSome())
assert.Equal(t, []int{2, 2, 2}, chunk2.Unwrap())
chunk3 := iterator.Next()
assert.True(t, chunk3.IsSome())
assert.Equal(t, []int{3, 3}, chunk3.Unwrap())
assert.True(t, iterator.Next().IsNone())
func Cloned ¶
Cloned creates an iterator which clones all of its elements. This function accepts Iterator[*T] and returns Iterator[T] for chainable calls.
func Empty ¶
Empty creates an iterator that yields no values.
Examples ¶
var iter = Empty[int]() assert.Equal(t, option.None[int](), iterator.Next())
func Enumerate ¶
Enumerate creates an iterator that yields pairs of (index, value). This function accepts Iterator[T] and returns Iterator[pair.Pair[uint, T]] for chainable calls.
func FilterMap ¶
FilterMap creates an iterator that both filters and maps.
The returned iterator yields only the values for which the supplied closure returns option.Some(value).
FilterMap can be used to make chains of Filter and Map more concise. The example below shows how a Map().Filter().Map() can be shortened to a single call to FilterMap.
Examples ¶
Basic usage:
var a = []string{"1", "two", "NaN", "four", "5"}
var iter = FilterMap(FromSlice(a), func(s string) option.Option[int] {
if v, err := strconv.Atoi(s); err == nil {
return option.Some(v)
}
return option.None[int]()
})
assert.Equal(t, option.Some(1), iterator.Next())
assert.Equal(t, option.Some(5), iterator.Next())
assert.Equal(t, option.None[int](), iterator.Next())
FilterMap creates an iterator that both filters and maps. This function accepts Iterator[T] and returns Iterator[U] for chainable calls.
func FlatMap ¶
FlatMap creates an iterator that works like map, but flattens nested structure.
The Map adapter is very useful, but only when the closure argument produces values. If it produces an iterator instead, there's an extra layer of indirection. FlatMap() will remove this extra layer on its own.
You can think of FlatMap(f) as the semantic equivalent of Mapping, and then Flattening as in Map(f).Flatten().
Another way of thinking about FlatMap(): Map's closure returns one item for each element, and FlatMap()'s closure returns an iterator for each element.
Examples ¶
var words = []string{"alpha", "beta", "gamma"}
var iter = FlatMap(FromSlice(words), func(s string) Iterator[rune] {
return FromSlice([]rune(s))
})
var result = Collect[rune](iter)
// result contains all characters from all words
func Flatten ¶
Flatten creates an iterator that flattens nested structure.
This is useful when you have an iterator of iterators or an iterator of things that can be turned into iterators and you want to remove one level of indirection.
Examples ¶
Basic usage:
var data = [][]int{{1, 2, 3, 4}, {5, 6}}
var iter = Flatten(FromSlice(data))
var result = Collect[int](iter)
// result is []int{1, 2, 3, 4, 5, 6}
func FromBitSet ¶
FromBitSet creates an iterator over all bits in a bit set, yielding pairs of (offset, bool) where offset is the bit position and bool indicates whether the bit is set.
Examples ¶
// Assuming you have a BitSet implementation
type MyBitSet struct {
bits []byte
}
func (b *MyBitSet) Size() int { return len(b.bits) * 8 }
func (b *MyBitSet) Get(offset int) bool {
if offset < 0 || offset >= b.Size() {
return false
}
byteIdx := offset / 8
bitIdx := offset % 8
return (b.bits[byteIdx] & (1 << (7 - bitIdx))) != 0
}
bitset := &MyBitSet{bits: []byte{0b10101010}}
iter := FromBitSet(bitset)
pair := iterator.Next()
assert.True(t, pair.IsSome())
assert.Equal(t, 0, pair.Unwrap().A) // offset
assert.Equal(t, true, pair.Unwrap().B) // bit value
// Filter only set bits
setBits := FromBitSet(bitset).
Filter(func(p pair.Pair[int, bool]) bool { return p.B }).
Map(func(p pair.Pair[int, bool]) int { return p.A }).
Collect()
func FromBitSetBytes ¶
FromBitSetBytes creates an iterator over all bits in a byte slice, treating the bytes as a bit set and yielding pairs of (offset, bool) where offset is the bit position (0-indexed from the first byte, first bit) and bool indicates whether the bit is set.
Bits are ordered from the most significant bit (MSB) to the least significant bit (LSB) within each byte, and bytes are ordered from first to last.
Examples ¶
bytes := []byte{0b10101010, 0b11001100}
iter := FromBitSetBytes(bytes)
pair := iterator.Next()
assert.True(t, pair.IsSome())
assert.Equal(t, 0, pair.Unwrap().A) // offset
assert.Equal(t, true, pair.Unwrap().B) // bit value (MSB of first byte)
// Get all set bit offsets
setBits := FromBitSetBytes(bytes).
Filter(func(p pair.Pair[int, bool]) bool { return p.B }).
Map(func(p pair.Pair[int, bool]) int { return p.A }).
Collect()
// setBits contains [0, 2, 4, 6, 8, 9, 12, 13]
// Count set bits
count := FromBitSetBytes(bytes).
Filter(func(p pair.Pair[int, bool]) bool { return p.B }).
Count()
func FromBitSetBytesOnes ¶
FromBitSetBytesOnes creates an iterator over only the bits that are set to true (1) in a byte slice (treated as a bit set), yielding the offset of each set bit.
Examples ¶
bytes := []byte{0b10101010, 0b11001100}
iter := FromBitSetBytesOnes(bytes)
assert.Equal(t, option.Some(0), iterator.Next()) // first set bit
assert.Equal(t, option.Some(2), iterator.Next()) // second set bit
assert.Equal(t, option.Some(4), iterator.Next()) // third set bit
// ... continues with all set bits
func FromBitSetBytesZeros ¶
FromBitSetBytesZeros creates an iterator over only the bits that are set to false (0) in a byte slice (treated as a bit set), yielding the offset of each unset bit.
Examples ¶
bytes := []byte{0b10101010, 0b11001100}
iter := FromBitSetBytesZeros(bytes)
assert.Equal(t, option.Some(1), iterator.Next()) // first unset bit
assert.Equal(t, option.Some(3), iterator.Next()) // second unset bit
assert.Equal(t, option.Some(5), iterator.Next()) // third unset bit
// ... continues with all unset bits
func FromBitSetOnes ¶
func FromBitSetOnes(bitset BitSetLike) Iterator[int]
FromBitSetOnes creates an iterator over only the bits that are set to true (1) in a bit set, yielding the offset of each set bit.
Examples ¶
bitset := &MyBitSet{bits: []byte{0b10101010}}
iter := FromBitSetOnes(bitset)
assert.Equal(t, option.Some(0), iterator.Next()) // first set bit
assert.Equal(t, option.Some(2), iterator.Next()) // second set bit
assert.Equal(t, option.Some(4), iterator.Next()) // third set bit
assert.Equal(t, option.Some(6), iterator.Next()) // fourth set bit
assert.Equal(t, option.None[int](), iterator.Next())
// Chain with other iterator methods
sum := FromBitSetOnes(bitset).
Filter(func(offset int) bool { return offset > 2 }).
Fold(0, func(acc, offset int) int { return acc + offset })
func FromBitSetZeros ¶
func FromBitSetZeros(bitset BitSetLike) Iterator[int]
FromBitSetZeros creates an iterator over only the bits that are set to false (0) in a bit set, yielding the offset of each unset bit.
Examples ¶
bitset := &MyBitSet{bits: []byte{0b10101010}}
iter := FromBitSetZeros(bitset)
assert.Equal(t, option.Some(1), iterator.Next()) // first unset bit
assert.Equal(t, option.Some(3), iterator.Next()) // second unset bit
assert.Equal(t, option.Some(5), iterator.Next()) // third unset bit
assert.Equal(t, option.Some(7), iterator.Next()) // fourth unset bit
assert.Equal(t, option.None[int](), iterator.Next())
func FromElements ¶
FromElements creates an iterator from a set of elements.
Examples ¶
var iter = FromElements(1, 2, 3) assert.Equal(t, option.Some(1), iterator.Next()) assert.Equal(t, option.Some(2), iterator.Next()) assert.Equal(t, option.Some(3), iterator.Next()) assert.Equal(t, option.None[int](), iterator.Next())
func FromFunc ¶
FromFunc creates an iterator from a function that generates values.
The function is called repeatedly until it returns option.None[T]().
Examples ¶
var count = 0
var iter = FromFunc(func() option.Option[int] {
if count < 3 {
count++
return option.Some(count)
}
return option.None[int]()
})
assert.Equal(t, option.Some(1), iterator.Next())
assert.Equal(t, option.Some(2), iterator.Next())
assert.Equal(t, option.Some(3), iterator.Next())
assert.Equal(t, option.None[int](), iterator.Next())
func FromIterable ¶
FromIterable creates an iterator from a gust.Iterable[T]. If the data is already an Iterator[T], it returns the same iterator. If the data is an Iterable[T], it returns an Iterator[T] with the core. If the data is a gust.Iterable[T], it returns an Iterator[T] with the iterable wrapper.
Examples ¶
var iter = FromIterable(FromSlice([]int{1, 2, 3}))
assert.Equal(t, option.Some(1), iterator.Next())
assert.Equal(t, option.Some(2), iterator.Next())
assert.Equal(t, option.Some(3), iterator.Next())
assert.Equal(t, option.None[int](), iterator.Next())
func FromPull ¶
FromPull creates an Iterator[T] from a pull-style iterator (next and stop functions). This allows converting pull-style iterators to gust iterators. Returns the iterator and a deferStop function that should be deferred to ensure proper cleanup.
Note: While the sequence will automatically clean up when it ends naturally (when next() returns false), it is recommended to always use "defer deferStop()" to ensure proper cleanup in all cases, including early termination.
Examples ¶
// Convert a pull-style iterator to gust Iterator
next, stop := iterator.Pull(someSeq)
defer stop()
gustIter, deferStop := FromPull(next, stop)
defer deferStop()
result := gustIter.Filter(func(x int) bool { return x > 2 }).Collect()
// Works with custom pull-style iterators
customNext := func() (int, bool) {
// custom implementation
return 0, false
}
customStop := func() {}
gustIter, deferStop = FromPull(customNext, customStop)
defer deferStop()
func FromPull2 ¶
func FromPull2[K any, V any](next func() (K, V, bool), stop func()) (Iterator[pair.Pair[K, V]], func())
FromPull2 creates an Iterator[pair.Pair[K, V]] from a pull-style iterator (next and stop functions). This allows converting pull-style key-value iterators to gust pair iterators. Returns the iterator and a deferStop function that should be deferred to ensure proper cleanup.
Note: While the sequence will automatically clean up when it ends naturally (when next() returns false), it is recommended to always use "defer deferStop()" to ensure proper cleanup in all cases, including early termination.
Examples ¶
// Convert a pull-style iterator to gust Iterator
next, stop := iterator.Pull2(someSeq2)
defer stop()
gustIter, deferStop := FromPull2(next, stop)
defer deferStop()
result := gustIter.Filter(func(p pair.Pair[int, string]) bool {
return p.B != ""
}).Collect()
// Works with custom pull-style iterators
customNext := func() (int, string, bool) {
// custom implementation
return 0, "", false
}
customStop := func() {}
gustIter, deferStop = FromPull2(customNext, customStop)
defer deferStop()
func FromRange ¶
func FromRange[T constraints.Integer](start T, end T) Iterator[T]
FromRange creates an iterator from a range of integers.
The range is [start, end), meaning start is inclusive and end is exclusive.
Examples ¶
var iter = FromRange(0, 5) assert.Equal(t, option.Some(0), iterator.Next()) assert.Equal(t, option.Some(1), iterator.Next()) assert.Equal(t, option.Some(2), iterator.Next()) assert.Equal(t, option.Some(3), iterator.Next()) assert.Equal(t, option.Some(4), iterator.Next()) assert.Equal(t, option.None[int](), iterator.Next())
func FromSeq ¶
FromSeq creates an Iterator[T] from Go's standard iterator.Seq[T]. This allows converting Go standard iterators to gust iterators. Returns the iterator and a deferStop function that should be deferred to ensure proper cleanup.
Note: While the sequence will automatically clean up when it ends naturally (when next() returns false), it is recommended to always use "defer deferStop()" to ensure proper cleanup in all cases, including early termination.
Examples ¶
// Convert a Go range iterator to gust Iterator
seq := func(yield func(int) bool) {
for i := 0; i < 5; i++ {
if !yield(i) {
return
}
}
}
iter, deferStop := FromSeq(seq)
defer deferStop() // Recommended: ensures cleanup even if iteration ends naturally
assert.Equal(t, option.Some(0), iterator.Next())
assert.Equal(t, option.Some(1), iterator.Next())
// Works with Go's standard library iterators
iter, deferStop = FromSeq(iterator.N(5)) // iterator.N(5) returns iterator.Seq[int]
defer deferStop()
assert.Equal(t, option.Some(0), iterator.Next())
func FromSeq2 ¶
FromSeq2 creates an Iterator[pair.Pair[K, V]] from Go's standard iterator.Seq2[K, V]. This allows converting Go standard key-value iterators to gust pair iterators. Returns the iterator and a deferStop function that should be deferred to ensure proper cleanup.
Note: While the sequence will automatically clean up when it ends naturally (when next() returns false), it is recommended to always use "defer deferStop()" to ensure proper cleanup in all cases, including early termination.
Examples ¶
// Convert a Go map iterator to gust Iterator
m := map[string]int{"a": 1, "b": 2, "c": 3}
seq2 := func(yield func(string, int) bool) {
for k, v := range m {
if !yield(k, v) {
return
}
}
}
iter, deferStop := FromSeq2(seq2)
defer deferStop()
pair := iterator.Next()
assert.True(t, pair.IsSome())
assert.Contains(t, []string{"a", "b", "c"}, pair.Unwrap().A)
// Works with Go's standard library iterators
iter, deferStop = FromSeq2(maps.All(myMap)) // maps.All returns iterator.Seq2[K, V]
defer deferStop()
func FromSlice ¶
FromSlice creates an iterator from a slice.
The returned iterator supports double-ended iteration, allowing iteration from both ends. Use AsDoubleEnded() to convert to DoubleEndedIterator.
Examples ¶
var a = []int{1, 2, 3}
var iter = FromSlice(a)
assert.Equal(t, option.Some(1), iterator.Next())
assert.Equal(t, option.Some(2), iterator.Next())
assert.Equal(t, option.Some(3), iterator.Next())
assert.Equal(t, option.None[int](), iterator.Next())
// As DoubleEndedIterator:
var deIter = AsDoubleEnded(FromSlice([]int{1, 2, 3, 4, 5, 6}))
assert.Equal(t, option.Some(1), deIter.Next())
assert.Equal(t, option.Some(6), deIter.NextBack())
assert.Equal(t, option.Some(5), deIter.NextBack())
func Map ¶
Map creates an iterator which calls a closure on each element.
Map() transforms one iterator into another, by means of its argument: something that implements a function. It produces a new iterator which calls this closure on each element of the original iterator.
If you are good at thinking in types, you can think of Map() like this: If you have an iterator that gives you elements of some type T, and you want an iterator of some other type U, you can use Map(), passing a closure that takes a T and returns a U.
Map() is conceptually similar to a for loop. However, as Map() is lazy, it is best used when you're already working with other iterators. If you're doing some sort of looping for a side effect, it's considered more idiomatic to use for than Map().
Examples ¶
Basic usage:
var a = []int{1, 2, 3}
var iter = Map(FromSlice(a), func(x int) int { return 2 * x })
assert.Equal(t, option.Some(2), iterator.Next())
assert.Equal(t, option.Some(4), iterator.Next())
assert.Equal(t, option.Some(6), iterator.Next())
assert.Equal(t, option.None[int](), iterator.Next())
Map creates an iterator which calls a closure on each element. This function accepts Iterator[T] and returns Iterator[U] for chainable calls.
func MapWhile ¶
MapWhile creates an iterator that both yields elements based on a predicate and maps.
MapWhile() takes a closure as an argument. It will call this closure on each element of the iterator, and yield elements while it returns option.Some(_).
Examples ¶
Basic usage:
var a = []int{-1, 4, 0, 1}
var iter = MapWhile(FromSlice(a), func(x int) option.Option[int] {
if x != 0 {
return option.Some(16 / x)
}
return option.None[int]()
})
assert.Equal(t, option.Some(-16), iterator.Next())
assert.Equal(t, option.Some(4), iterator.Next())
assert.Equal(t, option.None[int](), iterator.Next())
func MapWindows ¶
MapWindows creates an iterator that applies a function to overlapping windows of a given size.
The windows are arrays of a fixed size that overlap. The first window contains the first N elements, the second window contains elements [1..N+1], etc.
Panics ¶
Panics if window_size is 0 or if the iterator has fewer than window_size elements.
Examples ¶
var iter = MapWindows(FromSlice([]int{1, 2, 3, 4, 5}), 3, func(window []int) int {
return window[0] + window[1] + window[2]
})
assert.Equal(t, option.Some(6), iterator.Next()) // 1+2+3
assert.Equal(t, option.Some(9), iterator.Next()) // 2+3+4
assert.Equal(t, option.Some(12), iterator.Next()) // 3+4+5
assert.Equal(t, option.None[int](), iterator.Next())
func Once ¶
Once creates an iterator that yields a single value.
Examples ¶
Once creates an iterator that yields a value exactly once.
Examples ¶
var iter = Once(42) assert.Equal(t, option.Some(42), iterator.Next()) assert.Equal(t, option.None[int](), iterator.Next())
func OptMap ¶
OptMap creates an iterator which calls a closure on each element and returns a Option[*U]. NOTE:
`non-nil pointer` is wrapped as Some, and `nil pointer` is wrapped as None.
Examples ¶
iter := OptMap(FromSlice([]string{"1", "2", "3", "NaN"}), func(s string) *int {
if v, err := strconv.Atoi(s); err == nil {
return &v
} else {
return nil
}
})
var newInt = func(v int) *int {
return &v
}
assert.Equal(t, option.Some(option.Some(newInt(1))), iterator.Next()) assert.Equal(t, option.Some(option.Some(newInt(2))), iterator.Next()) assert.Equal(t, option.Some(option.Some(newInt(3))), iterator.Next()) assert.Equal(t, option.Some(option.None[*int]()), iterator.Next()) assert.Equal(t, option.None[option.Option[*int]](), iterator.Next())
func Repeat ¶
Repeat creates an iterator that repeats a value endlessly.
Examples ¶
var iter = Repeat(42) assert.Equal(t, option.Some(42), iterator.Next()) assert.Equal(t, option.Some(42), iterator.Next()) assert.Equal(t, option.Some(42), iterator.Next()) // ... continues forever
func RetMap ¶
RetMap creates an iterator which calls a closure on each element and returns a Result[U].
Examples ¶
iter := RetMap(FromSlice([]string{"1", "2", "3", "NaN"}), strconv.Atoi)
assert.Equal(t, option.Some(result.Ok(1)), iterator.Next()) assert.Equal(t, option.Some(result.Ok(2)), iterator.Next()) assert.Equal(t, option.Some(result.Ok(3)), iterator.Next()) assert.Equal(t, true, iterator.Next().Unwrap().IsErr()) assert.Equal(t, option.None[result.Result[int]](), iterator.Next())
func Scan ¶
func Scan[T any, U any, St any](iter Iterator[T], initialState St, f func(*St, T) option.Option[U]) Iterator[U]
Scan is an iterator adapter which, like Fold, holds internal state, but unlike Fold, produces a new iterator.
Scan() takes two arguments: an initial value which seeds the internal state, and a closure with two arguments, the first being a mutable reference to the internal state and the second an iterator element. The closure can assign to the internal state to share state between iterations.
On iteration, the closure will be applied to each element of the iterator and the return value from the closure, an option.Option, is returned by the Next() method. Thus the closure can return option.Some(value) to yield value, or option.None[T]() to end the iteration.
Examples ¶
var a = []int{1, 2, 3, 4}
var iter = Scan(FromSlice(a), 1, func(state *int, x int) option.Option[int] {
*state = *state * x
if *state > 6 {
return option.None[int]()
}
return option.Some(-*state)
})
assert.Equal(t, option.Some(-1), iterator.Next())
assert.Equal(t, option.Some(-2), iterator.Next())
assert.Equal(t, option.Some(-6), iterator.Next())
assert.Equal(t, option.None[int](), iterator.Next())
func Zip ¶
Zip 'zips up' two iterators into a single iterator of pairs.
Zip() returns a new iterator that will iterate over two other iterators, returning a tuple where the first element comes from the first iterator, and the second element comes from the second iterator.
In other words, it zips two iterators together, into a single one.
If either iterator returns option.None[T](), Next() from the zipped iterator will return option.None[T]().
Examples ¶
Basic usage:
var s1 = FromSlice([]rune{'a', 'b', 'c'})
var s2 = FromSlice([]rune{'d', 'e', 'f'})
var iter = Zip(s1, s2)
assert.Equal(t, option.Some(pair.Pair[rune, rune]{A: 'a', B: 'd'}), iterator.Next())
assert.Equal(t, option.Some(pair.Pair[rune, rune]{A: 'b', B: 'e'}), iterator.Next())
assert.Equal(t, option.Some(pair.Pair[rune, rune]{A: 'c', B: 'f'}), iterator.Next())
assert.Equal(t, option.None[pair.Pair[rune, rune]](), iterator.Next())
Zip creates an iterator that zips two iterators together. This function accepts Iterator[T] and Iterator[U] and returns Iterator[pair.Pair[T, U]] for chainable calls.
func (Iterator[T]) AdvanceBy ¶
func (it Iterator[T]) AdvanceBy(n uint) result.VoidResult
AdvanceBy advances the iterator by n elements.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4})
assert.True(t, iterator.AdvanceBy(2).IsOk())
func (Iterator[T]) All ¶
All tests if all elements satisfy a predicate.
Examples ¶
var iter = FromSlice([]int{2, 4, 6})
assert.True(t, iterator.All(func(x int) bool { return x%2 == 0 }))
func (Iterator[T]) Any ¶
Any tests if any element satisfies a predicate.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
assert.True(t, iterator.Any(func(x int) bool { return x > 2 }))
func (Iterator[T]) Chain ¶
Chain takes two iterators and creates a new iterator over both in sequence.
Examples ¶
var iter1 = FromSlice([]int{1, 2, 3})
var iter2 = FromSlice([]int{4, 5, 6})
var chained = iter1.Chain(iter2)
assert.Equal(t, option.Some(1), chained.Next())
func (Iterator[T]) Collect ¶
func (it Iterator[T]) Collect() []T
Collect collects all items into a slice.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var result = iterator.Collect()
assert.Equal(t, []int{1, 2, 3}, result)
func (Iterator[T]) Count ¶
Count consumes the iterator, counting the number of iterations.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4, 5})
assert.Equal(t, uint(5), iterator.Count())
func (Iterator[T]) Cycle ¶
Cycle repeats an iterator endlessly.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var cycled = iterator.Cycle()
assert.Equal(t, option.Some(1), cycled.Next())
assert.Equal(t, option.Some(2), cycled.Next())
assert.Equal(t, option.Some(3), cycled.Next())
assert.Equal(t, option.Some(1), cycled.Next()) // starts over
func (Iterator[T]) Filter ¶
Filter creates an iterator which uses a closure to determine if an element should be yielded.
Examples ¶
var iter = FromSlice([]int{0, 1, 2})
var filtered = iterator.Filter(func(x int) bool { return x > 0 })
assert.Equal(t, option.Some(1), filtered.Next())
func (Iterator[T]) FilterMap ¶
FilterMap creates an iterator that both filters and maps.
Examples ¶
var iter = FromSlice([]string{"1", "two", "NaN", "four", "5"})
var filtered = iterator.FilterMap(func(s string) option.Option[string] {
if s == "1" || s == "5" {
return option.Some(s)
}
return option.None[string]()
})
// Can chain: filtered.Filter(...).Collect()
func (Iterator[T]) Find ¶
Find searches for an element that satisfies a predicate.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
assert.Equal(t, option.Some(2), iterator.Find(func(x int) bool { return x > 1 }))
func (Iterator[T]) FindMap ¶
FindMap searches for an element and maps it.
Examples ¶
var iter = FromSlice([]string{"lol", "NaN", "2", "5"})
var firstNumber = iterator.FindMap(func(s string) option.Option[int] {
if v, err := strconv.Atoi(s); err == nil {
return option.Some(v)
}
return option.None[int]()
})
assert.Equal(t, option.Some(2), firstNumber)
func (Iterator[T]) FlatMap ¶
FlatMap creates an iterator that maps and flattens nested iterators.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var flatMapped = iterator.FlatMap(func(x int) Iterator[int] {
return FromSlice([]int{x, x * 2})
})
// Can chain: flatMapped.Filter(...).Collect()
func (Iterator[T]) Fold ¶
func (it Iterator[T]) Fold(init T, f func(T, T) T) T
Fold folds every element into an accumulator. This wrapper method allows Fold to be called as a method.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var sum = iterator.Fold(0, func(acc int, x int) int { return acc + x })
assert.Equal(t, 6, sum)
func (Iterator[T]) ForEach ¶
func (it Iterator[T]) ForEach(f func(T))
ForEach calls a closure on each element.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
iterator.ForEach(func(x int) { fmt.Println(x) })
func (Iterator[T]) Fuse ¶
Fuse creates an iterator that ends after the first None.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var fused = iterator.Fuse()
// After None, it will always return None
func (Iterator[T]) Inspect ¶
Inspect creates an iterator that calls a closure on each element for side effects.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var inspected = iterator.Inspect(func(x int) { fmt.Println(x) })
// Prints 1, 2, 3 when iterated
func (Iterator[T]) Intersperse ¶
Intersperse creates an iterator that places a separator between adjacent items.
Examples ¶
var iter = FromSlice([]int{0, 1, 2})
var interspersed = iterator.Intersperse(100)
assert.Equal(t, option.Some(0), interspersed.Next())
assert.Equal(t, option.Some(100), interspersed.Next())
func (Iterator[T]) IntersperseWith ¶
IntersperseWith creates an iterator that places an item generated by separator between adjacent items.
Examples ¶
var iter = FromSlice([]int{0, 1, 2})
var interspersed = iterator.IntersperseWith(func() int { return 99 })
assert.Equal(t, option.Some(0), interspersed.Next())
assert.Equal(t, option.Some(99), interspersed.Next())
func (Iterator[T]) Last ¶
Last returns the last element of the iterator.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
assert.Equal(t, option.Some(3), iterator.Last())
func (Iterator[T]) Map ¶
Map creates an iterator which calls a closure on each element.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var doubled = iterator.Map(func(x int) int { return x * 2 })
assert.Equal(t, option.Some(2), doubled.Next())
// Can chain: doubled.Filter(...).Collect()
func (Iterator[T]) MapWhile ¶
MapWhile creates an iterator that both yields elements based on a predicate and maps.
func (Iterator[T]) MapWindows ¶
MapWindows creates an iterator that applies a function to overlapping windows.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4, 5})
var windows = iterator.MapWindows(3, func(window []int) int {
return window[0] + window[1] + window[2]
})
// Can chain: windows.Filter(...).Collect()
func (Iterator[T]) MaxBy ¶
MaxBy returns the element that gives the maximum value with respect to the specified comparison function.
Examples ¶
var iter = FromSlice([]int{-3, 0, 1, 5, -10})
var max = iterator.MaxBy(func(x, y int) int {
if x < y {
return -1
}
if x > y {
return 1
}
return 0
})
assert.Equal(t, option.Some(5), max)
func (Iterator[T]) MinBy ¶
MinBy returns the element that gives the minimum value with respect to the specified comparison function.
Examples ¶
var iter = FromSlice([]int{-3, 0, 1, 5, -10})
var min = iterator.MinBy(func(x, y int) int {
if x < y {
return -1
}
if x > y {
return 1
}
return 0
})
assert.Equal(t, option.Some(-10), min)
func (Iterator[T]) MustToDoubleEnded ¶
func (it Iterator[T]) MustToDoubleEnded() DoubleEndedIterator[T]
MustToDoubleEnded converts to a DoubleEndedIterator[T] if the underlying iterator supports double-ended iteration. Otherwise, it panics.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var deIter = iterator.MustToDoubleEnded()
assert.Equal(t, option.Some(3), deIter.NextBack())
// Can use Iterator methods:
var doubled = deIter.Map(func(x int) any { return x * 2 })
func (Iterator[T]) Next ¶
Next advances the iterator and returns the next value. This implements gust.Iterable[T] interface.
func (Iterator[T]) NextChunk ¶
func (it Iterator[T]) NextChunk(n uint) ChunkResult[[]T]
NextChunk advances the iterator and returns an array containing the next N values.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4, 5})
chunk := iterator.NextChunk(2)
assert.True(t, chunk.IsOk())
func (Iterator[T]) Nth ¶
Nth returns the nth element of the iterator.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
assert.Equal(t, option.Some(2), iterator.Nth(1))
func (Iterator[T]) Partition ¶
Partition partitions the iterator into two slices.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4, 5})
evens, odds := iterator.Partition(func(x int) bool { return x%2 == 0 })
assert.Equal(t, []int{2, 4}, evens)
assert.Equal(t, []int{1, 3, 5}, odds)
func (Iterator[T]) Peekable ¶
func (it Iterator[T]) Peekable() PeekableIterator[T]
func (Iterator[T]) Position ¶
Position searches for an element in an iterator, returning its index.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
assert.Equal(t, option.Some(uint(1)), iterator.Position(func(x int) bool { return x == 2 }))
func (Iterator[T]) Pull ¶
Pull converts the Iterator[T] to a pull-style iterator using Go's standard iterator.Pull. This returns two functions: next (to pull values) and stop (to stop iteration). The caller should defer stop() to ensure proper cleanup.
Examples ¶
iter := FromSlice([]int{1, 2, 3, 4, 5})
next, stop := iterator.Pull()
defer stop()
// Pull values manually
for {
v, ok := next()
if !ok {
break
}
fmt.Println(v)
if v == 3 {
break // Early termination
}
}
func (Iterator[T]) Pull2 ¶
Pull2 converts the Iterator[T] to a pull-style iterator using Go's standard iterator.Pull2. This returns two functions: next (to pull key-value pairs) and stop (to stop iteration). The caller should defer stop() to ensure proper cleanup.
Examples ¶
iter := FromSlice([]int{1, 2, 3, 4, 5})
next, stop := iterator.Pull2()
defer stop()
// Pull key-value pairs manually
for {
k, v, ok := next()
if !ok {
break
}
fmt.Println(k, v)
if v == 3 {
break // Early termination
}
}
func (Iterator[T]) Reduce ¶
Reduce reduces the iterator to a single value.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var sum = iterator.Reduce(func(acc int, x int) int { return acc + x })
assert.Equal(t, option.Some(6), sum)
func (Iterator[T]) Scan ¶
Scan creates an iterator that scans over the iterator with a state.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var scanned = iterator.Scan(0, func(state *int, x int) option.Option[int] {
*state = *state + x
return option.Some(*state)
})
// Can chain: scanned.Filter(...).Collect()
func (Iterator[T]) Seq ¶
Seq converts the Iterator[T] to Go's standard iterator.Seq[T]. This allows using gust iterators with Go's built-in iteration support (for loops).
Examples ¶
iter := FromSlice([]int{1, 2, 3})
for v := range iterator.Seq() {
fmt.Println(v) // prints 1, 2, 3
}
func (Iterator[T]) Seq2 ¶
Seq2 converts the Iterator[T] to Go's standard iterator.Seq2[T]. This allows using gust iterators with Go's built-in iteration support (for loops).
Examples ¶
iter := FromSlice([]int{1, 2, 3})
for k, v := range iterator.Seq2() {
fmt.Println(k, v) // prints 0 1, 1 2, 2 3
}
func (Iterator[T]) SizeHint ¶
SizeHint returns the bounds on the remaining length of the iterator. This implements gust.IterableSizeHint interface.
func (Iterator[T]) Skip ¶
Skip creates an iterator that skips the first n elements.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var skipped = iterator.Skip(2)
assert.Equal(t, option.Some(3), skipped.Next())
func (Iterator[T]) SkipWhile ¶
SkipWhile creates an iterator that skips elements while predicate returns true.
Examples ¶
var iter = FromSlice([]int{-1, 0, 1})
var skipped = iterator.SkipWhile(func(x int) bool { return x < 0 })
assert.Equal(t, option.Some(0), skipped.Next())
func (Iterator[T]) StepBy ¶
StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.
Panics ¶
Panics if step is 0.
Examples ¶
var iter = FromSlice([]int{0, 1, 2, 3, 4, 5})
var stepped = iterator.StepBy(2)
assert.Equal(t, option.Some(0), stepped.Next())
assert.Equal(t, option.Some(2), stepped.Next())
assert.Equal(t, option.Some(4), stepped.Next())
func (Iterator[T]) Take ¶
Take creates an iterator that yields the first n elements.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var taken = iterator.Take(2)
assert.Equal(t, option.Some(1), taken.Next())
assert.Equal(t, option.Some(2), taken.Next())
assert.Equal(t, option.None[int](), taken.Next())
func (Iterator[T]) TakeWhile ¶
TakeWhile creates an iterator that yields elements while predicate returns true.
Examples ¶
var iter = FromSlice([]int{-1, 0, 1})
var taken = iterator.TakeWhile(func(x int) bool { return x < 0 })
assert.Equal(t, option.Some(-1), taken.Next())
assert.Equal(t, option.None[int](), taken.Next())
func (Iterator[T]) TryFind ¶
TryFind applies function to the elements of iterator and returns the first true result or the first error.
This is the fallible version of Find().
Examples ¶
var a = []string{"1", "2", "lol", "NaN", "5"}
var res = iterator.TryFind(func(s string) result.Result[bool] {
if s == "lol" {
return result.TryErr[bool](errors.New("invalid"))
}
if v, err := strconv.Atoi(s); err == nil {
return result.Ok(v == 2)
}
return result.Ok(false)
})
assert.True(t, result.IsOk())
func (Iterator[T]) TryFold ¶
TryFold applies a function as long as it returns successfully, producing a single, final value.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var sum = iterator.TryFold(0, func(acc int, x int) result.Result[int] {
return result.Ok(acc + x)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap())
func (Iterator[T]) TryForEach ¶
TryForEach applies a fallible function to each item in the iterator, stopping at the first error and returning that error.
Examples ¶
var data = []string{"no_tea.txt", "stale_bread.json", "torrential_rain.png"}
var res = iterator.TryForEach(func(x string) result.Result[string] {
fmt.Println(x)
return result.Ok[string](x+"_processed")
})
assert.True(t, res.IsOk())
assert.Equal(t, "no_tea.txt_processed", res.Unwrap())
func (Iterator[T]) TryReduce ¶
TryReduce reduces the elements to a single one by repeatedly applying a reducing operation.
Examples ¶
var numbers = []int{10, 20, 5, 23, 0}
var sum = iterator.TryReduce(func(x, y int) result.Result[int] {
if x+y > 100 {
return result.TryErr[int](errors.New("overflow"))
}
return result.Ok(x + y)
})
assert.True(t, sum.IsOk())
func (Iterator[T]) TryToDoubleEnded ¶
func (it Iterator[T]) TryToDoubleEnded() option.Option[DoubleEndedIterator[T]]
TryToDoubleEnded converts to a DoubleEndedIterator[T] if the underlying iterator supports double-ended iteration. Otherwise, it returns None.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var deIter = iterator.TryToDoubleEnded()
assert.Equal(t, option.Some(3), deIter.NextBack())
// Can use Iterator methods:
var doubled = deIter.Map(func(x int) any { return x * 2 })
func (Iterator[T]) XFilterMap ¶
XFilterMap creates an iterator that both filters and maps (any version).
Examples ¶
var iter = FromSlice([]string{"1", "two", "NaN", "four", "5"})
var filtered = iterator.XFilterMap(func(s string) option.Option[any] {
if s == "1" {
return option.Some(any(1))
}
if s == "5" {
return option.Some(any(5))
}
return option.None[any]()
})
// Can chain: filtered.Filter(...).Collect()
func (Iterator[T]) XFindMap ¶
XFindMap searches for an element and maps it (any version).
Examples ¶
var iter = FromSlice([]string{"lol", "NaN", "2", "5"})
var firstNumber = iterator.XFindMap(func(s string) option.Option[any] {
if v, err := strconv.Atoi(s); err == nil {
return option.Some(any(v))
}
return option.None[any]()
})
assert.True(t, firstNumber.IsSome())
assert.Equal(t, 2, firstNumber.Unwrap().(int))
func (Iterator[T]) XFlatMap ¶
XFlatMap creates an iterator that maps and flattens nested iterators (any version).
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var flatMapped = iterator.XFlatMap(func(x int) Iterator[any] {
return FromSlice([]any{x, x * 2})
})
// Can chain: flatMapped.Filter(...).Collect()
func (Iterator[T]) XFold ¶
XFold folds every element into an accumulator. This wrapper method allows XFold to be called as a method.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var sum = iterator.XFold(0, func(acc any, x int) any { return acc.(int) + x })
assert.Equal(t, 6, sum)
func (Iterator[T]) XMap ¶
XMap creates an iterator which calls a closure on each element (any version).
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var doubled = iterator.XMap(func(x int) any { return x * 2 })
assert.Equal(t, option.Some(2), doubled.Next())
// Can chain: doubled.Filter(...).Collect()
func (Iterator[T]) XMapWhile ¶
XMapWhile creates an iterator that both yields elements based on a predicate and maps (any version).
func (Iterator[T]) XMapWindows ¶
XMapWindows creates an iterator that applies a function to overlapping windows (any version).
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4, 5})
var windows = iterator.XMapWindows(3, func(window []int) any {
return window[0] + window[1] + window[2]
})
// Can chain: windows.Filter(...).Collect()
func (Iterator[T]) XScan ¶
XScan creates an iterator that scans over the iterator with a state (any version).
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var scanned = iterator.XScan(0, func(state *any, x int) option.Option[any] {
s := (*state).(int) + x
*state = s
return option.Some(any(s))
})
// Can chain: scanned.Filter(...).Collect()
func (Iterator[T]) XTryFold ¶
XTryFold applies a function as long as it returns successfully, producing a single, final value (any version).
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var sum = iterator.XTryFold(0, func(acc any, x int) result.Result[any] {
return result.Ok[any](any(acc.(int) + x))
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap().(int))
func (Iterator[T]) XTryForEach ¶
XTryForEach applies a fallible function to each item in the iterator, stopping at the first error and returning that error.
Examples ¶
var data = []string{"no_tea.txt", "stale_bread.json", "torrential_rain.png"}
var res = iterator.TryForEach(func(x string) result.Result[any] {
fmt.Println(x)
return result.Ok[any](nil)
})
assert.True(t, res.IsOk())
type PeekableIterator ¶
type PeekableIterator[T any] struct { Iterator[T] // Embed Iterator to inherit all its methods // contains filtered or unexported fields }
Peekable creates a peekable iterator.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var peekable = iterator.Peekable()
assert.Equal(t, option.Some(1), peekable.Peek())
assert.Equal(t, option.Some(1), peekable.Next())
// Can use all Iterator methods:
var filtered = peekable.Filter(func(x int) bool { return x > 1 })
assert.Equal(t, option.Some(2), filtered.Next())
PeekableIterator is an iterator that supports peeking at the next element. It embeds Iterator[T] to inherit all Iterator methods, and adds Peek() method.
Examples ¶
var xs = []int{1, 2, 3}
var iter = Peekable(FromSlice(xs))
// peek() lets us see into the future
assert.Equal(t, option.Some(1), iterator.Peek())
assert.Equal(t, option.Some(1), iterator.Next())
// Can use all Iterator methods:
var filtered = iterator.Filter(func(x int) bool { return x > 1 })
assert.Equal(t, option.Some(2), filtered.Next())
func (*PeekableIterator[T]) Next ¶
func (p *PeekableIterator[T]) Next() option.Option[T]
Next advances the iterator and returns the next value. This overrides Iterator[T].Next() to handle peeked values.
func (*PeekableIterator[T]) Peek ¶
func (p *PeekableIterator[T]) Peek() option.Option[T]
Peek returns the next element without consuming it.
Examples ¶
var xs = []int{1, 2, 3}
var iter = Peekable(FromSlice(xs))
assert.Equal(t, option.Some(1), iterator.Peek())
assert.Equal(t, option.Some(1), iterator.Peek()) // Can peek multiple times
assert.Equal(t, option.Some(1), iterator.Next())
type SizeIterable ¶
type SizeIterable[T any] interface { Iterable[T] // Remaining returns the number of remaining elements. Remaining() uint }
SizeIterable represents an iterable that knows its remaining size.