Documentation
¶
Overview ¶
Package iter 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.
Index ¶
- func Cmp[T gust.Ord](a Iterator[T], b Iterator[T]) gust.Ordering
- func CmpBy[T any, U any](a Iterator[T], b Iterator[U], cmp func(T, U) int) gust.Ordering
- func DefaultSizeHint[T any]() (uint, gust.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) gust.Option[U]) gust.Option[U]
- func Fold[T any, B any](iter Iterator[T], init B, f func(B, T) B) B
- func Ge[T gust.Digit](a Iterator[T], b Iterator[T]) bool
- func Gt[T gust.Digit](a Iterator[T], b Iterator[T]) bool
- func IsSorted[T gust.Digit](iter Iterator[T]) bool
- func IsSortedBy[T any](iter Iterator[T], compare func(T, T) bool) bool
- func IsSortedByKey[T any, K gust.Digit](iter Iterator[T], f func(T) K) bool
- func Le[T gust.Digit](a Iterator[T], b Iterator[T]) bool
- func Lt[T gust.Digit](a Iterator[T], b Iterator[T]) bool
- func Max[T gust.Ord](iter Iterator[T]) gust.Option[T]
- func MaxByKey[T any, K gust.Ord](iter Iterator[T], f func(T) K) gust.Option[T]
- func Min[T gust.Ord](iter Iterator[T]) gust.Option[T]
- func MinByKey[T any, K gust.Ord](iter Iterator[T], f func(T) K) gust.Option[T]
- func Ne[T comparable](a Iterator[T], b Iterator[T]) bool
- func PartialCmp[T gust.Digit](a Iterator[T], b Iterator[T]) gust.Option[gust.Ordering]
- func PartialCmpBy[T any, U any](a Iterator[T], b Iterator[U], partialCmp func(T, U) gust.Option[gust.Ordering]) gust.Option[gust.Ordering]
- func Product[T gust.Digit](iter Iterator[T]) T
- func Pull2[K any, V any](it Iterator[gust.Pair[K, V]]) (next func() (K, V, bool), stop func())
- func Rfind[T any](de DoubleEndedIterator[T], predicate func(T) bool) gust.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[gust.Pair[K, V]]) stditer.Seq2[K, V]
- func Sum[T gust.Digit](iter Iterator[T]) T
- func TryFold[T any, B any](iter Iterator[T], init B, f func(B, T) gust.Result[B]) gust.Result[B]
- func TryForEach[T any, B any](iter Iterator[T], f func(T) gust.Result[B]) gust.Result[B]
- func TryRfold[T any, B any](de DoubleEndedIterator[T], init B, f func(B, T) gust.Result[B]) gust.Result[B]
- func Unzip[T any, U any](iter Iterator[gust.Pair[T, U]]) ([]T, []U)
- type BitSetLike
- type ChunkResult
- type DoubleEndedIterable
- type DoubleEndedIterator
- func (de DoubleEndedIterator[T]) AdvanceBackBy(n uint) gust.VoidResult
- func (de DoubleEndedIterator[T]) NextBack() gust.Option[T]
- func (de DoubleEndedIterator[T]) NthBack(n uint) gust.Option[T]
- func (de DoubleEndedIterator[T]) Remaining() uint
- func (de DoubleEndedIterator[T]) Rfind(predicate func(T) bool) gust.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) gust.Result[T]) gust.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) gust.Result[any]) gust.Result[any]
- type Iterable
- 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[gust.Pair[uint, T]]
- func FilterMap[T any, U any](iter Iterator[T], f func(T) gust.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[gust.Pair[int, bool]]
- func FromBitSetBytes(bytes []byte) Iterator[gust.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() gust.Option[T]) Iterator[T]
- func FromIterable[T any](data gust.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[gust.Pair[K, V]], func())
- func FromRange[T gust.Integer](start T, end T) Iterator[T]
- func FromSeq[T any](seq stditer.Seq[T]) (Iterator[T], func())
- func FromSeq2[K any, V any](seq stditer.Seq2[K, V]) (Iterator[gust.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) gust.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[gust.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[gust.Result[U]]
- func Scan[T any, U any, St any](iter Iterator[T], initialState St, f func(*St, T) gust.Option[U]) Iterator[U]
- func Zip[T any, U any](a Iterator[T], b Iterator[U]) Iterator[gust.Pair[T, U]]
- func (it Iterator[T]) AdvanceBy(n uint) gust.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) gust.Option[T]) Iterator[T]
- func (it Iterator[T]) Find(predicate func(T) bool) gust.Option[T]
- func (it Iterator[T]) FindMap(f func(T) gust.Option[T]) gust.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() gust.Option[T]
- func (it Iterator[T]) Map(f func(T) T) Iterator[T]
- func (it Iterator[T]) MapWhile(predicate func(T) gust.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) gust.Option[T]
- func (it Iterator[T]) MinBy(compare func(T, T) int) gust.Option[T]
- func (it Iterator[T]) MustToDoubleEnded() DoubleEndedIterator[T]
- func (it Iterator[T]) Next() gust.Option[T]
- func (it Iterator[T]) NextChunk(n uint) ChunkResult[[]T]
- func (it Iterator[T]) Nth(n uint) gust.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) gust.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) gust.Option[T]
- func (it Iterator[T]) Scan(initialState T, f func(*T, T) gust.Option[T]) Iterator[T]
- func (it Iterator[T]) Seq() stditer.Seq[T]
- func (it Iterator[T]) Seq2() stditer.Seq2[uint, T]
- func (it Iterator[T]) SizeHint() (uint, gust.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) gust.Result[bool]) gust.Result[gust.Option[T]]
- func (it Iterator[T]) TryFold(init T, f func(T, T) gust.Result[T]) gust.Result[T]
- func (it Iterator[T]) TryForEach(f func(T) gust.Result[T]) gust.Result[T]
- func (it Iterator[T]) TryReduce(f func(T, T) gust.Result[T]) gust.Result[gust.Option[T]]
- func (it Iterator[T]) TryToDoubleEnded() gust.Option[DoubleEndedIterator[T]]
- func (it Iterator[T]) XFilterMap(f func(T) gust.Option[any]) Iterator[any]
- func (it Iterator[T]) XFindMap(f func(T) gust.Option[any]) gust.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) gust.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) gust.Option[any]) Iterator[any]
- func (it Iterator[T]) XTryFold(init any, f func(any, T) gust.Result[any]) gust.Result[any]
- func (it Iterator[T]) XTryForEach(f func(T) gust.Result[any]) gust.Result[any]
- type PeekableIterator
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Cmp ¶ added in v1.7.0
Cmp lexicographically compares the elements of this Iterator with those of another.
Examples ¶
assert.Equal(t, gust.Less(), Cmp(FromSlice([]int{1}), FromSlice([]int{1})))
assert.Equal(t, gust.Less(), Cmp(FromSlice([]int{1}), FromSlice([]int{1, 2})))
assert.Equal(t, gust.Greater(), Cmp(FromSlice([]int{1, 2}), FromSlice([]int{1})))
func CmpBy ¶ added in v1.7.0
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, gust.Equal(), result)
func DefaultSizeHint ¶ added in v1.7.0
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 ¶ added in v1.7.0
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 ¶ added in v1.7.0
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) gust.Option[int] {
if v, err := strconv.Atoi(s); err == nil {
return gust.Some(v)
}
return gust.None[int]()
})
assert.Equal(t, gust.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 ¶ added in v1.7.0
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 ¶ added in v1.7.0
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 ¶ added in v1.7.0
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 ¶ added in v1.7.0
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 ¶ added in v1.7.0
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 ¶ added in v1.7.0
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 ¶ added in v1.7.0
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 ¶ added in v1.7.0
Max returns the maximum element of an iterator.
If several elements are equally maximum, the last element is returned. If the iterator is empty, gust.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, gust.Some(3), Max(FromSlice(a)))
assert.Equal(t, gust.None[int](), Max(FromSlice(b)))
func MaxByKey ¶ added in v1.7.0
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, gust.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, gust.Some(-10), max)
func Min ¶ added in v1.7.0
Min returns the minimum element of an iterator.
If several elements are equally minimum, the first element is returned. If the iterator is empty, gust.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, gust.Some(1), Min(FromSlice(a)))
assert.Equal(t, gust.None[int](), Min(FromSlice(b)))
func MinByKey ¶ added in v1.7.0
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, gust.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, gust.Some(0), min)
func Ne ¶ added in v1.7.0
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 ¶ added in v1.7.0
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, gust.Some(gust.Equal()), result)
var result2 = PartialCmp(FromSlice([]float64{1.0}), FromSlice([]float64{1.0, 2.0}))
assert.Equal(t, gust.Some(gust.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, gust.None[gust.Ordering](), result3)
func PartialCmpBy ¶ added in v1.7.0
func PartialCmpBy[T any, U any](a Iterator[T], b Iterator[U], partialCmp func(T, U) gust.Option[gust.Ordering]) gust.Option[gust.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) gust.Option[gust.Ordering] {
if x*x < y {
return gust.Some(gust.Less())
}
if x*x > y {
return gust.Some(gust.Greater())
}
return gust.Some(gust.Equal())
})
assert.Equal(t, gust.Some(gust.Equal()), result)
func Product ¶ added in v1.7.0
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 ¶ added in v1.9.0
Pull2 converts the Iterator[gust.Pair[K, V]] to a pull-style iterator using Go's standard iter.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 ¶ added in v1.7.0
func Rfind[T any](de DoubleEndedIterator[T], predicate func(T) bool) gust.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, gust.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 ¶ added in v1.9.0
Seq2 converts the Iterator[gust.Pair[K, V]] to Go's standard iter.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 ¶ added in v1.7.0
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 ¶
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) gust.Result[int] {
// Simulate checked addition
if acc > 100 {
return gust.Err[int](errors.New("overflow"))
}
return gust.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) gust.Result[int] {
if acc+x > 50 {
return gust.Err[int](errors.New("overflow"))
}
return gust.Ok(acc + x)
})
assert.True(t, sum.IsErr())
func TryForEach ¶ added in v1.7.0
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) gust.Result[any] {
fmt.Println(x)
return gust.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) gust.Result[B]) gust.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) gust.Result[int] {
if v, err := strconv.Atoi(s); err == nil {
return gust.Ok(acc + v)
}
return gust.Err[int](err)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap())
func Unzip ¶ added in v1.7.0
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 = []gust.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 ¶ added in v1.12.0
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 ¶ added in v1.10.0
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 ¶ added in v1.10.0
func (r ChunkResult[T]) IsErr() bool
IsErr returns true if the result is an error.
func (ChunkResult[T]) IsOk ¶ added in v1.10.0
func (r ChunkResult[T]) IsOk() bool
IsOk returns true if the result is ok.
func (ChunkResult[T]) Unwrap ¶ added in v1.10.0
func (r ChunkResult[T]) Unwrap() T
Unwrap returns the contained T value.
func (ChunkResult[T]) UnwrapErr ¶ added in v1.10.0
func (r ChunkResult[T]) UnwrapErr() T
UnwrapErr returns the contained error T value.
type DoubleEndedIterable ¶ added in v1.7.0
type DoubleEndedIterable[T any] interface { Iterable[T] // Includes Next() and SizeHint() gust.DoubleEndedIterable[T] // Includes NextBack() and Remaining() }
DoubleEndedIterable is the interface for double-ended iterator implementations.
type DoubleEndedIterator ¶ added in v1.7.0
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()
assert.Equal(t, gust.Some(1), deIter.Next())
assert.Equal(t, gust.Some(6), deIter.NextBack())
assert.Equal(t, gust.Some(5), deIter.NextBack())
assert.Equal(t, gust.Some(2), deIter.Next())
assert.Equal(t, gust.Some(3), deIter.Next())
assert.Equal(t, gust.Some(4), deIter.Next())
assert.Equal(t, gust.None[int](), deIter.Next())
assert.Equal(t, gust.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 ¶ added in v1.7.0
func (de DoubleEndedIterator[T]) AdvanceBackBy(n uint) gust.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, gust.Some(4), deIter.NextBack())
assert.True(t, deIter.AdvanceBackBy(0).IsOk())
assert.True(t, deIter.AdvanceBackBy(100).IsErr())
func (DoubleEndedIterator[T]) NextBack ¶ added in v1.7.0
func (de DoubleEndedIterator[T]) NextBack() gust.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, gust.Some(6), deIter.NextBack())
assert.Equal(t, gust.Some(5), deIter.NextBack())
assert.Equal(t, gust.Some(4), deIter.NextBack())
assert.Equal(t, gust.Some(3), deIter.NextBack())
assert.Equal(t, gust.Some(2), deIter.NextBack())
assert.Equal(t, gust.Some(1), deIter.NextBack())
assert.Equal(t, gust.None[int](), deIter.NextBack())
func (DoubleEndedIterator[T]) NthBack ¶ added in v1.7.0
func (de DoubleEndedIterator[T]) NthBack(n uint) gust.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, gust.Some(1), deIter.NthBack(2))
assert.Equal(t, gust.Some(2), deIter.NthBack(1))
assert.Equal(t, gust.Some(3), deIter.NthBack(0))
assert.Equal(t, gust.None[int](), deIter.NthBack(10))
func (DoubleEndedIterator[T]) Remaining ¶ added in v1.8.0
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 ¶ added in v1.7.0
func (de DoubleEndedIterator[T]) Rfind(predicate func(T) bool) gust.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, gust.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, gust.None[int](), deIter2.Rfind(func(x int) bool { return x == 5 }))
func (DoubleEndedIterator[T]) Rfold ¶ added in v1.7.0
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 ¶ added in v1.7.0
func (de DoubleEndedIterator[T]) TryRfold(init T, f func(T, T) gust.Result[T]) gust.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) gust.Result[int] {
if v, err := strconv.Atoi(s); err == nil {
return gust.Ok(acc + v)
}
return gust.Err[int](err)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap())
func (DoubleEndedIterator[T]) XRfold ¶ added in v1.7.0
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 = iter.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 ¶ added in v1.7.0
func (de DoubleEndedIterator[T]) XTryRfold(init any, f func(any, T) gust.Result[any]) gust.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) gust.Result[any] {
if v, err := strconv.Atoi(s); err == nil {
return gust.Ok(any(acc.(int) + v))
}
return gust.Err[any](err)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap().(int))
type Iterable ¶ added in v1.7.0
type Iterable[T any] interface { gust.Iterable[T] gust.IterableSizeHint }
Iterable is the interface that extends gust.Iterable[T] and gust.IterableSizeHint. This is used internally for concrete iterator implementations.
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: iter.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 = iter.Filter(func(x int) bool { return x > 2 }).
Take(2).
Collect()
func ArrayChunks ¶ added in v1.7.0
func Cloned ¶ added in v1.7.0
Cloned creates an iterator which clones all of its elements. This function accepts Iterator[*T] and returns Iterator[T] for chainable calls.
func Empty ¶ added in v1.7.0
Empty creates an iterator that yields no values.
Examples ¶
var iter = Empty[int]() assert.Equal(t, gust.None[int](), iter.Next())
func Enumerate ¶
Enumerate creates an iterator that yields pairs of (index, value). This function accepts Iterator[T] and returns Iterator[gust.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 gust.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) gust.Option[int] {
if v, err := strconv.Atoi(s); err == nil {
return gust.Some(v)
}
return gust.None[int]()
})
assert.Equal(t, gust.Some(1), iter.Next())
assert.Equal(t, gust.Some(5), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())
FilterMap creates an iterator that both filters and maps. This function accepts Iterator[T] and returns Iterator[U] for chainable calls.
func FlatMap ¶ added in v0.8.0
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 FromBitSet ¶ added in v1.12.0
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 := iter.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 gust.Pair[int, bool]) bool { return p.B }).
Map(func(p gust.Pair[int, bool]) int { return p.A }).
Collect()
func FromBitSetBytes ¶ added in v1.12.0
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 := iter.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 gust.Pair[int, bool]) bool { return p.B }).
Map(func(p gust.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 gust.Pair[int, bool]) bool { return p.B }).
Count()
func FromBitSetBytesOnes ¶ added in v1.12.0
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, gust.Some(0), iter.Next()) // first set bit
assert.Equal(t, gust.Some(2), iter.Next()) // second set bit
assert.Equal(t, gust.Some(4), iter.Next()) // third set bit
// ... continues with all set bits
func FromBitSetBytesZeros ¶ added in v1.12.0
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, gust.Some(1), iter.Next()) // first unset bit
assert.Equal(t, gust.Some(3), iter.Next()) // second unset bit
assert.Equal(t, gust.Some(5), iter.Next()) // third unset bit
// ... continues with all unset bits
func FromBitSetOnes ¶ added in v1.12.0
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, gust.Some(0), iter.Next()) // first set bit
assert.Equal(t, gust.Some(2), iter.Next()) // second set bit
assert.Equal(t, gust.Some(4), iter.Next()) // third set bit
assert.Equal(t, gust.Some(6), iter.Next()) // fourth set bit
assert.Equal(t, gust.None[int](), iter.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 ¶ added in v1.12.0
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, gust.Some(1), iter.Next()) // first unset bit
assert.Equal(t, gust.Some(3), iter.Next()) // second unset bit
assert.Equal(t, gust.Some(5), iter.Next()) // third unset bit
assert.Equal(t, gust.Some(7), iter.Next()) // fourth unset bit
assert.Equal(t, gust.None[int](), iter.Next())
func FromElements ¶
FromElements creates an iterator from a set of elements.
Examples ¶
var iter = FromElements(1, 2, 3) assert.Equal(t, gust.Some(1), iter.Next()) assert.Equal(t, gust.Some(2), iter.Next()) assert.Equal(t, gust.Some(3), iter.Next()) assert.Equal(t, gust.None[int](), iter.Next())
func FromFunc ¶ added in v1.7.0
FromFunc creates an iterator from a function that generates values.
The function is called repeatedly until it returns gust.None[T]().
Examples ¶
var count = 0
var iter = FromFunc(func() gust.Option[int] {
if count < 3 {
count++
return gust.Some(count)
}
return gust.None[int]()
})
assert.Equal(t, gust.Some(1), iter.Next())
assert.Equal(t, gust.Some(2), iter.Next())
assert.Equal(t, gust.Some(3), iter.Next())
assert.Equal(t, gust.None[int](), iter.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, gust.Some(1), iter.Next())
assert.Equal(t, gust.Some(2), iter.Next())
assert.Equal(t, gust.Some(3), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())
func FromPull ¶ added in v1.9.0
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 := iter.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 ¶ added in v1.9.0
func FromPull2[K any, V any](next func() (K, V, bool), stop func()) (Iterator[gust.Pair[K, V]], func())
FromPull2 creates an Iterator[gust.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 := iter.Pull2(someSeq2)
defer stop()
gustIter, deferStop := FromPull2(next, stop)
defer deferStop()
result := gustIter.Filter(func(p gust.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 ¶
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, gust.Some(0), iter.Next()) assert.Equal(t, gust.Some(1), iter.Next()) assert.Equal(t, gust.Some(2), iter.Next()) assert.Equal(t, gust.Some(3), iter.Next()) assert.Equal(t, gust.Some(4), iter.Next()) assert.Equal(t, gust.None[int](), iter.Next())
func FromSeq ¶ added in v1.9.0
FromSeq creates an Iterator[T] from Go's standard iter.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, gust.Some(0), iter.Next())
assert.Equal(t, gust.Some(1), iter.Next())
// Works with Go's standard library iterators
iter, deferStop = FromSeq(iter.N(5)) // iter.N(5) returns iter.Seq[int]
defer deferStop()
assert.Equal(t, gust.Some(0), iter.Next())
func FromSeq2 ¶ added in v1.9.0
FromSeq2 creates an Iterator[gust.Pair[K, V]] from Go's standard iter.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 := iter.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 iter.Seq2[K, V]
defer deferStop()
func FromSlice ¶ added in v1.7.0
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, gust.Some(1), iter.Next())
assert.Equal(t, gust.Some(2), iter.Next())
assert.Equal(t, gust.Some(3), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())
// As DoubleEndedIterator:
var deIter = AsDoubleEnded(FromSlice([]int{1, 2, 3, 4, 5, 6}))
assert.Equal(t, gust.Some(1), deIter.Next())
assert.Equal(t, gust.Some(6), deIter.NextBack())
assert.Equal(t, gust.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, gust.Some(2), iter.Next())
assert.Equal(t, gust.Some(4), iter.Next())
assert.Equal(t, gust.Some(6), iter.Next())
assert.Equal(t, gust.None[int](), iter.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 gust.Some(_).
Examples ¶
Basic usage:
var a = []int{-1, 4, 0, 1}
var iter = MapWhile(FromSlice(a), func(x int) gust.Option[int] {
if x != 0 {
return gust.Some(16 / x)
}
return gust.None[int]()
})
assert.Equal(t, gust.Some(-16), iter.Next())
assert.Equal(t, gust.Some(4), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())
func MapWindows ¶ added in v1.7.0
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, gust.Some(6), iter.Next()) // 1+2+3
assert.Equal(t, gust.Some(9), iter.Next()) // 2+3+4
assert.Equal(t, gust.Some(12), iter.Next()) // 3+4+5
assert.Equal(t, gust.None[int](), iter.Next())
func Once ¶ added in v1.7.0
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, gust.Some(42), iter.Next()) assert.Equal(t, gust.None[int](), iter.Next())
func OptMap ¶ added in v1.8.0
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, gust.Some(gust.Some(newInt(1))), iter.Next()) assert.Equal(t, gust.Some(gust.Some(newInt(2))), iter.Next()) assert.Equal(t, gust.Some(gust.Some(newInt(3))), iter.Next()) assert.Equal(t, gust.Some(gust.None[*int]()), iter.Next()) assert.Equal(t, gust.None[gust.Option[*int]](), iter.Next())
func Repeat ¶ added in v1.7.0
Repeat creates an iterator that repeats a value endlessly.
Examples ¶
var iter = Repeat(42) assert.Equal(t, gust.Some(42), iter.Next()) assert.Equal(t, gust.Some(42), iter.Next()) assert.Equal(t, gust.Some(42), iter.Next()) // ... continues forever
func RetMap ¶ added in v1.8.0
assert.Equal(t, gust.Some(gust.Ok(1)), iter.Next()) assert.Equal(t, gust.Some(gust.Ok(2)), iter.Next()) assert.Equal(t, gust.Some(gust.Ok(3)), iter.Next()) assert.Equal(t, true, iter.Next().Unwrap().IsErr()) assert.Equal(t, gust.None[gust.Result[int]](), iter.Next())
func Scan ¶ added in v0.8.0
func Scan[T any, U any, St any](iter Iterator[T], initialState St, f func(*St, T) gust.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 gust.Option, is returned by the Next() method. Thus the closure can return gust.Some(value) to yield value, or gust.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) gust.Option[int] {
*state = *state * x
if *state > 6 {
return gust.None[int]()
}
return gust.Some(-*state)
})
assert.Equal(t, gust.Some(-1), iter.Next())
assert.Equal(t, gust.Some(-2), iter.Next())
assert.Equal(t, gust.Some(-6), iter.Next())
assert.Equal(t, gust.None[int](), iter.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 gust.None[T](), Next() from the zipped iterator will return gust.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, gust.Some(gust.Pair[rune, rune]{A: 'a', B: 'd'}), iter.Next())
assert.Equal(t, gust.Some(gust.Pair[rune, rune]{A: 'b', B: 'e'}), iter.Next())
assert.Equal(t, gust.Some(gust.Pair[rune, rune]{A: 'c', B: 'f'}), iter.Next())
assert.Equal(t, gust.None[gust.Pair[rune, rune]](), iter.Next())
Zip creates an iterator that zips two iterators together. This function accepts Iterator[T] and Iterator[U] and returns Iterator[gust.Pair[T, U]] for chainable calls.
func (Iterator[T]) AdvanceBy ¶
func (it Iterator[T]) AdvanceBy(n uint) gust.VoidResult
AdvanceBy advances the iterator by n elements.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4})
assert.True(t, iter.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, iter.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, iter.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, gust.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 = iter.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), iter.Count())
func (Iterator[T]) Cycle ¶ added in v1.7.0
Cycle repeats an iterator endlessly.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var cycled = iter.Cycle()
assert.Equal(t, gust.Some(1), cycled.Next())
assert.Equal(t, gust.Some(2), cycled.Next())
assert.Equal(t, gust.Some(3), cycled.Next())
assert.Equal(t, gust.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 = iter.Filter(func(x int) bool { return x > 0 })
assert.Equal(t, gust.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 = iter.FilterMap(func(s string) gust.Option[string] {
if s == "1" || s == "5" {
return gust.Some(s)
}
return gust.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, gust.Some(2), iter.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 = iter.FindMap(func(s string) gust.Option[int] {
if v, err := strconv.Atoi(s); err == nil {
return gust.Some(v)
}
return gust.None[int]()
})
assert.Equal(t, gust.Some(2), firstNumber)
func (Iterator[T]) FlatMap ¶ added in v1.7.0
FlatMap creates an iterator that maps and flattens nested iterators.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var flatMapped = iter.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 = iter.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})
iter.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 = iter.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 = iter.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 = iter.Intersperse(100)
assert.Equal(t, gust.Some(0), interspersed.Next())
assert.Equal(t, gust.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 = iter.IntersperseWith(func() int { return 99 })
assert.Equal(t, gust.Some(0), interspersed.Next())
assert.Equal(t, gust.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, gust.Some(3), iter.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 = iter.Map(func(x int) int { return x * 2 })
assert.Equal(t, gust.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 ¶ added in v1.7.0
MapWindows creates an iterator that applies a function to overlapping windows.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4, 5})
var windows = iter.MapWindows(3, func(window []int) int {
return window[0] + window[1] + window[2]
})
// Can chain: windows.Filter(...).Collect()
func (Iterator[T]) MaxBy ¶ added in v1.7.0
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 = iter.MaxBy(func(x, y int) int {
if x < y {
return -1
}
if x > y {
return 1
}
return 0
})
assert.Equal(t, gust.Some(5), max)
func (Iterator[T]) MinBy ¶ added in v1.7.0
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 = iter.MinBy(func(x, y int) int {
if x < y {
return -1
}
if x > y {
return 1
}
return 0
})
assert.Equal(t, gust.Some(-10), min)
func (Iterator[T]) MustToDoubleEnded ¶ added in v1.7.0
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 = iter.MustToDoubleEnded()
assert.Equal(t, gust.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 := iter.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, gust.Some(2), iter.Nth(1))
func (Iterator[T]) Partition ¶ added in v1.0.0
Partition partitions the iterator into two slices.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4, 5})
evens, odds := iter.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]
Peekable creates a peekable iterator.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var peekable = iter.Peekable()
assert.Equal(t, gust.Some(1), peekable.Peek())
assert.Equal(t, gust.Some(1), peekable.Next())
// Can use all Iterator methods:
var filtered = peekable.Filter(func(x int) bool { return x > 1 })
assert.Equal(t, gust.Some(2), filtered.Next())
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, gust.Some(uint(1)), iter.Position(func(x int) bool { return x == 2 }))
func (Iterator[T]) Pull ¶ added in v1.9.0
Pull converts the Iterator[T] to a pull-style iterator using Go's standard iter.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 := iter.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 ¶ added in v1.9.1
Pull2 converts the Iterator[T] to a pull-style iterator using Go's standard iter.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 := iter.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 = iter.Reduce(func(acc int, x int) int { return acc + x })
assert.Equal(t, gust.Some(6), sum)
func (Iterator[T]) Scan ¶ added in v0.8.0
Scan creates an iterator that scans over the iterator with a state.
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var scanned = iter.Scan(0, func(state *int, x int) gust.Option[int] {
*state = *state + x
return gust.Some(*state)
})
// Can chain: scanned.Filter(...).Collect()
func (Iterator[T]) Seq ¶ added in v1.9.0
Seq converts the Iterator[T] to Go's standard iter.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 iter.Seq() {
fmt.Println(v) // prints 1, 2, 3
}
func (Iterator[T]) Seq2 ¶ added in v1.9.1
Seq2 converts the Iterator[T] to Go's standard iter.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 iter.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 ¶ added in v0.8.0
Skip creates an iterator that skips the first n elements.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4, 5})
var skipped = iter.Skip(2)
assert.Equal(t, gust.Some(3), skipped.Next())
func (Iterator[T]) SkipWhile ¶
SkipWhile creates an iterator that skips elements while a predicate is true.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4, 5})
var skipped = iter.SkipWhile(func(x int) bool { return x < 3 })
assert.Equal(t, gust.Some(3), skipped.Next())
func (Iterator[T]) StepBy ¶
StepBy creates an iterator that steps by n elements at a time.
Examples ¶
var iter = FromSlice([]int{0, 1, 2, 3, 4, 5})
var stepped = iter.StepBy(2)
assert.Equal(t, gust.Some(0), stepped.Next())
assert.Equal(t, gust.Some(2), stepped.Next())
assert.Equal(t, gust.Some(4), stepped.Next())
func (Iterator[T]) Take ¶ added in v0.8.0
Take creates an iterator that yields the first n elements.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4, 5})
var taken = iter.Take(2)
assert.Equal(t, gust.Some(1), taken.Next())
assert.Equal(t, gust.Some(2), taken.Next())
assert.Equal(t, gust.None[int](), taken.Next())
func (Iterator[T]) TakeWhile ¶
TakeWhile creates an iterator that yields elements while a predicate is true.
Examples ¶
var iter = FromSlice([]int{1, 2, 3, 4, 5})
var taken = iter.TakeWhile(func(x int) bool { return x < 3 })
assert.Equal(t, gust.Some(1), taken.Next())
assert.Equal(t, gust.Some(2), taken.Next())
assert.Equal(t, gust.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.
Examples ¶
var a = []string{"1", "2", "lol", "NaN", "5"}
var result = iter.TryFind(func(s string) gust.Result[bool] {
if s == "lol" {
return gust.Err[bool](errors.New("invalid"))
}
if v, err := strconv.Atoi(s); err == nil {
return gust.Ok(v == 2)
}
return gust.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 = iter.TryFold(0, func(acc int, x int) gust.Result[int] {
return gust.Ok(acc + x)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap())
func (Iterator[T]) TryForEach ¶ added in v1.0.0
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 = iter.TryForEach(func(x string) gust.Result[string] {
fmt.Println(x)
return gust.Ok[string](x+"_processed")
})
assert.True(t, res.IsOk())
assert.Equal(t, "no_tea.txt_processed", res.Unwrap())
func (Iterator[T]) TryReduce ¶ added in v1.0.0
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 = iter.TryReduce(func(x, y int) gust.Result[int] {
if x+y > 100 {
return gust.Err[int](errors.New("overflow"))
}
return gust.Ok(x + y)
})
assert.True(t, sum.IsOk())
func (Iterator[T]) TryToDoubleEnded ¶ added in v1.7.0
func (it Iterator[T]) TryToDoubleEnded() gust.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 = iter.TryToDoubleEnded()
assert.Equal(t, gust.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 = iter.XFilterMap(func(s string) gust.Option[any] {
if s == "1" {
return gust.Some(any(1))
}
if s == "5" {
return gust.Some(any(5))
}
return gust.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 = iter.XFindMap(func(s string) gust.Option[any] {
if v, err := strconv.Atoi(s); err == nil {
return gust.Some(any(v))
}
return gust.None[any]()
})
assert.True(t, firstNumber.IsSome())
assert.Equal(t, 2, firstNumber.Unwrap().(int))
func (Iterator[T]) XFlatMap ¶ added in v1.7.0
XFlatMap creates an iterator that maps and flattens nested iterators (any version).
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var flatMapped = iter.XFlatMap(func(x int) Iterator[any] {
return FromSlice([]any{x, x * 2})
})
// Can chain: flatMapped.Filter(...).Collect()
func (Iterator[T]) XFold ¶ added in v1.7.0
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 = iter.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 = iter.XMap(func(x int) any { return x * 2 })
assert.Equal(t, gust.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 ¶ added in v1.7.0
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 = iter.XMapWindows(3, func(window []int) any {
return window[0] + window[1] + window[2]
})
// Can chain: windows.Filter(...).Collect()
func (Iterator[T]) XScan ¶ added in v1.7.0
XScan creates an iterator that scans over the iterator with a state (any version).
Examples ¶
var iter = FromSlice([]int{1, 2, 3})
var scanned = iter.XScan(0, func(state *any, x int) gust.Option[any] {
s := (*state).(int) + x
*state = s
return gust.Some(any(s))
})
// Can chain: scanned.Filter(...).Collect()
func (Iterator[T]) XTryFold ¶ added in v1.7.0
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 = iter.XTryFold(0, func(acc any, x int) gust.Result[any] {
return gust.Ok(any(acc.(int) + x))
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap().(int))
func (Iterator[T]) XTryForEach ¶ added in v1.7.0
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 = iter.TryForEach(func(x string) gust.Result[any] {
fmt.Println(x)
return gust.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 }
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, gust.Some(1), iter.Peek())
assert.Equal(t, gust.Some(1), iter.Next())
// Can use all Iterator methods:
var filtered = iter.Filter(func(x int) bool { return x > 1 })
assert.Equal(t, gust.Some(2), filtered.Next())
func (*PeekableIterator[T]) Next ¶ added in v1.7.0
func (p *PeekableIterator[T]) Next() gust.Option[T]
Next advances the iterator and returns the next value. This overrides Iterator[T].Next() to handle peeked values.
func (*PeekableIterator[T]) Peek ¶ added in v1.7.0
func (p *PeekableIterator[T]) Peek() gust.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, gust.Some(1), iter.Peek())
assert.Equal(t, gust.Some(1), iter.Peek()) // Can peek multiple times
assert.Equal(t, gust.Some(1), iter.Next())