Documentation
¶
Overview ¶
Package xiter provides the abstraction of map, slice or channel types into iterators for common processing In most scenarios, we DO NOT need to use the xiter package directly
WARNING: golang 1.23 has higher performance on iterating Seq/Seq2 which boost by coroutine we provide for low golang version just for compatible usage
Index ¶
- func AllFromSeq[T any](seq Seq[T], f func(T) bool) bool
- func AnyFromSeq[T any](seq Seq[T], f func(T) bool) bool
- func At[T any](seq Seq[T], index int) optional.O[T]
- func AvgByFromSeq[V any, T constraints.Number](seq Seq[V], f func(V) T) float64
- func AvgFromSeq[T constraints.Number](seq Seq[T]) float64
- func Contains[T comparable](seq Seq[T], in T) bool
- func ContainsAll[T comparable](seq Seq[T], in []T) bool
- func ContainsAny[T comparable](seq Seq[T], in []T) bool
- func ContainsBy[T any](seq Seq[T], f func(T) bool) bool
- func Count[T any](seq Seq[T]) int
- func Equal[V comparable](x, y Seq[V]) bool
- func Equal2[K, V comparable](x, y Seq2[K, V]) bool
- func EqualFunc[V1, V2 any](x Seq[V1], y Seq[V2], f func(V1, V2) bool) bool
- func EqualFunc2[K1, V1, K2, V2 any](x Seq2[K1, V1], y Seq2[K2, V2], f func(K1, V1, K2, V2) bool) bool
- func Find[T any](seq Seq[T], f func(T) bool) (val T, found bool)
- func FindO[T any](seq Seq[T], f func(T) bool) optional.O[T]
- func ForEach[T any](seq Seq[T], f func(T) bool)
- func ForEachIdx[T any](seq Seq[T], f func(idx int, v T) bool)
- func Head[T any](seq Seq[T]) (v T, hasOne bool)
- func HeadO[T any](seq Seq[T]) optional.O[T]
- func Index[T comparable](seq Seq[T], v T) int
- func Join[T ~string](seq Seq[T], sep T) T
- func Max[T constraints.Ordered](seq Seq[T]) (r optional.O[T])
- func MaxBy[T constraints.Ordered](seq Seq[T], less func(T, T) bool) (r optional.O[T])
- func Min[T constraints.Ordered](seq Seq[T]) (r optional.O[T])
- func MinBy[T constraints.Ordered](seq Seq[T], less func(T, T) bool) (r optional.O[T])
- func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func())
- func Pull2[K, V any](seq Seq2[K, V]) (next func() (K, V, bool), stop func())
- func Reduce[Sum, V any](f func(Sum, V) Sum, sum Sum, seq Seq[V]) Sum
- func Reduce2[Sum, K, V any](f func(Sum, K, V) Sum, sum Sum, seq Seq2[K, V]) Sum
- func Sum[T constraints.Number](seq Seq[T]) T
- func ToMap[K comparable, V any](seq Seq2[K, V]) (out map[K]V)
- func ToSlice[T any](seq Seq[T]) (out []T)
- func ToSliceN[T any](seq Seq[T], n int) (out []T)
- func ToSliceSeq2Key[K, V any](seq Seq2[K, V]) (out []K)
- func ToSliceSeq2Value[K, V any](seq Seq2[K, V]) (out []V)
- type Seq
- func Chunk[T any](seq Seq[T], n int) Seq[[]T]
- func Concat[V any](seqs ...Seq[V]) Seq[V]
- func Filter[V any](f func(V) bool, seq Seq[V]) Seq[V]
- func FromMapKeys[K comparable, V any](m map[K]V) Seq[K]
- func FromMapValues[K comparable, V any](m map[K]V) Seq[V]
- func FromSlice[T any](in []T) Seq[T]
- func FromSliceReverse[T any, Slice ~[]T](in Slice) Seq[T]
- func FromSliceShuffle[T any](in []T) Seq[T]
- func Limit[V any](seq Seq[V], n int) Seq[V]
- func Map[In, Out any](f func(In) Out, seq Seq[In]) Seq[Out]
- func Merge[V cmp.Ordered](x, y Seq[V]) Seq[V]
- func MergeFunc[V any](x, y Seq[V], f func(V, V) int) Seq[V]
- func Repeat[T any](seq Seq[T], count int) Seq[T]
- func Replace[T comparable](seq Seq[T], from, to T, n int) Seq[T]
- func ReplaceAll[T comparable](seq Seq[T], from, to T) Seq[T]
- func Reverse[T any](seq Seq[T]) Seq[T]
- func Seq2KeyToSeq[K, V any](in Seq2[K, V]) Seq[K]
- func Seq2ToSeqUnion[K, V any](seq Seq2[K, V]) Seq[union.U2[K, V]]
- func Seq2ValueToSeq[K, V any](in Seq2[K, V]) Seq[V]
- func Skip[T any](seq Seq[T], n int) Seq[T]
- func Zip[V1, V2 any](x Seq[V1], y Seq[V2]) Seq[Zipped[V1, V2]]
- func Zip2[K1, V1, K2, V2 any](x Seq2[K1, V1], y Seq2[K2, V2]) Seq[Zipped2[K1, V1, K2, V2]]
- type Seq2
- func Concat2[K, V any](seqs ...Seq2[K, V]) Seq2[K, V]
- func Filter2[K, V any](f func(K, V) bool, seq Seq2[K, V]) Seq2[K, V]
- func FromMapKeyAndValues[K comparable, V any](m map[K]V) Seq2[K, V]
- func FromSliceIdx[T any](in []T) Seq2[int, T]
- func Limit2[K, V any](seq Seq2[K, V], n int) Seq2[K, V]
- func Map2[KIn, VIn, KOut, VOut any](f func(KIn, VIn) (KOut, VOut), seq Seq2[KIn, VIn]) Seq2[KOut, VOut]
- func Merge2[K cmp.Ordered, V any](x, y Seq2[K, V]) Seq2[K, V]
- func MergeFunc2[K, V any](x, y Seq2[K, V], f func(K, K) int) Seq2[K, V]
- type Zipped
- type Zipped2
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AllFromSeq ¶
AllFromSeq return true if all elements from seq satisfy the condition evaluated by f.
func AnyFromSeq ¶
AnyFromSeq return true if any elements from seq satisfy the condition evaluated by f.
func AvgByFromSeq ¶
func AvgByFromSeq[V any, T constraints.Number](seq Seq[V], f func(V) T) float64
AvgByFromSeq return the average value of all elements from seq, evaluated by f.
func AvgFromSeq ¶
func AvgFromSeq[T constraints.Number](seq Seq[T]) float64
AvgFromSeq return the average value of all elements from seq.
func Contains ¶
func Contains[T comparable](seq Seq[T], in T) bool
Contains return true if v is in seq.
func ContainsAll ¶
func ContainsAll[T comparable](seq Seq[T], in []T) bool
ContainsAll return true if all elements from seq is in vs.
func ContainsAny ¶
func ContainsAny[T comparable](seq Seq[T], in []T) bool
ContainsAny return true if any element from seq is in vs.
func ContainsBy ¶
ContainsBy return true if any element from seq satisfies the condition evaluated by f.
func Equal ¶
func Equal[V comparable](x, y Seq[V]) bool
Equal returns whether the two sequences are equal. It compares elements from both Seq in parallel. If the Seq have different lengths or if any corresponding elements are not equal, it returns false.
Example:
seq1 := xiter.FromSlice([]int{1, 2, 3})
seq2 := xiter.FromSlice([]int{1, 2, 3})
seq3 := xiter.FromSlice([]int{1, 2, 4})
fmt.Println(xiter.Equal(seq1, seq2))
fmt.Println(xiter.Equal(seq1, seq3))
// output:
// true
// false
Example ¶
package main
import (
"fmt"
"github.com/dashjay/xiter/pkg/xiter"
)
func main() {
seq1 := xiter.FromSlice([]int{1, 2, 3})
seq2 := xiter.FromSlice([]int{1, 2, 3})
seq3 := xiter.FromSlice([]int{1, 2, 4})
fmt.Println(xiter.Equal(seq1, seq2))
fmt.Println(xiter.Equal(seq1, seq3))
}
Output: true false
func Equal2 ¶
func Equal2[K, V comparable](x, y Seq2[K, V]) bool
Equal2 returns whether the two Seq2 are equal. Like Equal but run with Seq2
func EqualFunc ¶
EqualFunc returns whether the two sequences are equal according to the function f. Example:
seq1 := xiter.FromSlice([]int{6, 11, 16})
seq2 := xiter.FromSlice([]int{26, 36, 41})
seq3 := xiter.FromSlice([]int{1, 2, 4})
mod5Eq := func(a int, b int) bool {
return math.Mod(float64(a), 5) == math.Mod(float64(b), 5)
}
fmt.Println(xiter.EqualFunc(seq1, seq2, mod5Eq))
fmt.Println(xiter.EqualFunc(seq1, seq3, mod5Eq))
// output:
// true
// false
Example ¶
package main
import (
"fmt"
"math"
"github.com/dashjay/xiter/pkg/xiter"
)
func main() {
seq1 := xiter.FromSlice([]int{6, 11, 16})
seq2 := xiter.FromSlice([]int{26, 36, 41})
seq3 := xiter.FromSlice([]int{1, 2, 4})
mod5Eq := func(a int, b int) bool {
return math.Mod(float64(a), 5) == math.Mod(float64(b), 5)
}
fmt.Println(xiter.EqualFunc(seq1, seq2, mod5Eq))
fmt.Println(xiter.EqualFunc(seq1, seq3, mod5Eq))
}
Output: true false
func EqualFunc2 ¶
func EqualFunc2[K1, V1, K2, V2 any](x Seq2[K1, V1], y Seq2[K2, V2], f func(K1, V1, K2, V2) bool) bool
EqualFunc2 returns whether the two sequences are equal according to the function f. Like EqualFunc but run with Seq2
func Find ¶
Find return the first element from seq that satisfies the condition evaluated by f with a boolean representing whether it exists.
func ForEachIdx ¶
ForEachIdx execute f for each element in seq with its index.
func Head ¶
Head return the first element from seq with a boolean representing whether it is at least one element in seq.
func Index ¶ added in v0.0.2
func Index[T comparable](seq Seq[T], v T) int
Index returns the index of the first element in the sequence that is equal to v. If no such element is found, -1 is returned.
Example:
seq := xiter.FromSlice([]int{1, 2, 3, 4, 5})
idx := xiter.Index(seq, 3)
// idx is 2
func Max ¶
func Max[T constraints.Ordered](seq Seq[T]) (r optional.O[T])
Max returns the maximum element in seq.
func Min ¶
func Min[T constraints.Ordered](seq Seq[T]) (r optional.O[T])
Min return the minimum element in seq.
func Pull ¶
Pull wrapped iter.Pull create an iterator from seq. Example:
seq := xiter.FromSlice([]int{1, 2, 3})
next, stop := xiter.Pull(seq)
defer stop()
x, ok := next()
fmt.Println(x, ok)
// output:
// 1 true
Example ¶
package main
import (
"fmt"
"github.com/dashjay/xiter/pkg/xiter"
)
func main() {
seq := xiter.FromSlice([]int{1, 2, 3})
next, stop := xiter.Pull(seq)
defer stop()
x, ok := next()
fmt.Println(x, ok)
}
Output: 1 true
func Reduce ¶
Reduce combines the values in seq using f. For each value v in seq, it updates sum = f(sum, v) and then returns the final sum. For example, if iterating over seq yields v1, v2, v3, Reduce returns f(f(f(sum, v1), v2), v3). Example:
seq1To100 := xiter.FromSlice(_range(1, 101))
sum := xiter.Reduce(func(sum int, v int) int {
return sum + v
}, 0, seq1To100)
fmt.Println(sum)
// output:
// 5050
Example ¶
package main
import (
"fmt"
"github.com/dashjay/xiter/pkg/xiter"
)
func _range(a, b int) []int {
var res []int
for i := a; i < b; i++ {
res = append(res, i)
}
return res
}
func main() {
seq1To100 := xiter.FromSlice(_range(1, 101))
sum := xiter.Reduce(func(sum int, v int) int {
return sum + v
}, 0, seq1To100)
fmt.Println(sum)
}
Output: 5050
func Reduce2 ¶
Reduce2 combines the values in seq using f. For each pair k, v in seq, it updates sum = f(sum, k, v) and then returns the final sum. For example, if iterating over seq yields (k1, v1), (k2, v2), (k3, v3) Reduce returns f(f(f(sum, k1, v1), k2, v2), k3, v3).
func Sum ¶ added in v0.0.2
func Sum[T constraints.Number](seq Seq[T]) T
Sum returns the sum of all elements in the sequence.
Example:
seq := xiter.FromSlice([]int{1, 2, 3, 4, 5})
sum := xiter.Sum(seq)
// sum is 15
func ToMap ¶
func ToMap[K comparable, V any](seq Seq2[K, V]) (out map[K]V)
func ToSliceSeq2Key ¶
ToSliceSeq2Key returns the keys in seq as a slice.
Example:
seq := FromMap(map[string]int{"a": 1, "b": 2})
keys := ToSliceSeq2Key(seq)
// keys will contain: []string{"a", "b"} (order may vary)
func ToSliceSeq2Value ¶
ToSliceSeq2Value returns the values in seq as a slice.
Example:
seq := FromMap(map[string]int{"a": 1, "b": 2})
values := ToSliceSeq2Value(seq)
// values will contain: []int{1, 2} (order may vary)
Types ¶
type Seq ¶
Seq is a sequence of elements provided by an iterator-like function. We made this alias Seq to iter.Seq for providing a compatible interface in lower go versions.
func Chunk ¶ added in v0.0.2
Chunk divides a sequence into chunks of size n, yielding each chunk as a slice. The last chunk may contain fewer than n elements.
Example:
seq := xiter.FromSlice([]int{1, 2, 3, 4, 5})
chunkedSeq := xiter.Chunk(seq, 2)
// xiter.ToSlice(chunkedSeq) returns [][]int{{1,2}, {3,4}, {5}}
func Concat ¶
Concat returns a Seq over the concatenation of the sequences. It combines multiple Seqs into a single Seq by iterating each Seq one by one in order.
Example:
seq1 := xiter.FromSlice([]int{1, 2})
seq2 := xiter.FromSlice([]int{3, 4})
seq3 := xiter.FromSlice([]int{5, 6})
combined := xiter.Concat(seq1, seq2, seq3)
fmt.Println(xiter.ToSlice(combined))
// output:
// [1 2 3 4 5 6]
Example ¶
package main
import (
"fmt"
"github.com/dashjay/xiter/pkg/xiter"
)
func main() {
seq1 := xiter.FromSlice([]int{1, 2})
seq2 := xiter.FromSlice([]int{3, 4})
seq3 := xiter.FromSlice([]int{5, 6})
combined := xiter.Concat(seq1, seq2, seq3)
fmt.Println(xiter.ToSlice(combined))
}
Output: [1 2 3 4 5 6]
func Filter ¶
Filter returns a Seq over seq that only includes the values v for which f(v) is true.
Example:
seq := FromSlice([]int{1, 2, 3, 4, 5})
evenNumbers := Filter(func(v int) bool { return v%2 == 0 }, seq)
// evenNumbers will yield: 2, 4
Example ¶
package main
import (
"fmt"
"github.com/dashjay/xiter/pkg/xiter"
)
func main() {
seq := xiter.FromSlice([]int{1, 2, 3, 4, 5})
evenNumbers := xiter.Filter(func(v int) bool { return v%2 == 0 }, seq)
fmt.Println(xiter.ToSlice(evenNumbers))
}
Output: [2 4]
func FromMapKeys ¶
func FromMapKeys[K comparable, V any](m map[K]V) Seq[K]
func FromMapValues ¶
func FromMapValues[K comparable, V any](m map[K]V) Seq[V]
func FromSliceReverse ¶
func FromSliceShuffle ¶
FromSliceShuffle return a seq that shuffle the elements in the input slice.
Example:
seq := FromSlice([]int{1, 2, 3, 4, 5})
shuffledSeq := FromSliceShuffle(ToSlice(seq))
// shuffledSeq will yield a shuffled sequence of 1, 2, 3, 4, 5
func Limit ¶
Limit returns an iterator over the first n values of seq. If n is less than or equal to 0, an empty sequence is returned.
Example:
seq := xiter.FromSlice([]int{1, 2, 3, 4, 5})
limitedSeq := xiter.Limit(seq, 3)
fmt.Println(xiter.ToSlice(limitedSeq))
// output:
// [1 2 3]
Example ¶
package main
import (
"fmt"
"github.com/dashjay/xiter/pkg/xiter"
)
func main() {
seq := xiter.FromSlice([]int{1, 2, 3, 4, 5})
limitedSeq := xiter.Limit(seq, 3)
fmt.Println(xiter.ToSlice(limitedSeq))
}
Output: [1 2 3]
func Map ¶
Map returns a Seq over the results of applying f to each value in seq.
Example:
seq := xiter.FromSlice([]int{1, 2, 3})
doubled := xiter.Map(func(v int) int { return v * 2 }, seq)
fmt.Println(xiter.ToSlice(doubled))
// output:
// [2 4 6]
Example ¶
package main
import (
"fmt"
"github.com/dashjay/xiter/pkg/xiter"
)
func main() {
seq := xiter.FromSlice([]int{1, 2, 3})
doubled := xiter.Map(func(v int) int { return v * 2 }, seq)
fmt.Println(xiter.ToSlice(doubled))
}
Output: [2 4 6]
func Merge ¶
Merge merges two sequences of ordered values. Values appear in the output once for each time they appear in x and once for each time they appear in y. If the two input sequences are not ordered, the output sequence will not be ordered, but it will still contain every value from x and y exactly once.
Merge is equivalent to calling MergeFunc with cmp.Compare[V] as the ordering function.
Example ¶
package main
import (
"fmt"
"github.com/dashjay/xiter/pkg/xiter"
)
func main() {
oddSeq := xiter.FromSlice([]int{1, 3, 5})
evenSeq := xiter.FromSlice([]int{2, 4, 6})
mergedSeq := xiter.Merge(oddSeq, evenSeq)
fmt.Println(xiter.ToSlice(mergedSeq))
}
Output: [1 2 3 4 5 6]
func MergeFunc ¶
MergeFunc merges two sequences of values ordered by the function f. Values appear in the output once for each time they appear in x and once for each time they appear in y. When equal values appear in both sequences, the output contains the values from x before the values from y. If the two input sequences are not ordered by f, the output sequence will not be ordered by f, but it will still contain every value from x and y exactly once.
func Replace ¶
func Replace[T comparable](seq Seq[T], from, to T, n int) Seq[T]
Replace return a seq that replace from -> to
Example:
seq := FromSlice([]int{1, 2, 3, 2, 4})
replacedSeq := Replace(seq, 2, 99, -1) // Replace all 2s with 99
// replacedSeq will yield: 1, 99, 3, 99, 4
func ReplaceAll ¶
func ReplaceAll[T comparable](seq Seq[T], from, to T) Seq[T]
ReplaceAll return a seq that replace all from -> to
Example:
seq := FromSlice([]int{1, 2, 3, 2, 4})
replacedSeq := ReplaceAll(seq, 2, 99)
// replacedSeq will yield: 1, 99, 3, 99, 4
func Seq2KeyToSeq ¶
func Seq2ToSeqUnion ¶ added in v0.0.2
Seq2ToSeqUnion converts a Seq2 sequence of key-value pairs to a Seq sequence of union.U2 values. This allows unified processing of both keys and values from a key-value sequence.
Example:
seq2 := func(yield func(int, string) bool) { yield(1, "one"); yield(2, "two") }
for v := range Seq2ToSeqUnion(seq2) {
// v will be union.U2[int, string] containing either 1, "one", 2, or "two"
}
func Seq2ValueToSeq ¶
func Zip ¶
Zip returns an iterator that iterates x and y in parallel, yielding Zipped values of successive elements of x and y. If one sequence ends before the other, the iteration continues with Zipped values in which either Ok1 or Ok2 is false, depending on which sequence ended first.
Zip is a useful building block for adapters that process pairs of sequences. For example, Equal can be defined as:
func Equal[V comparable](x, y Seq[V]) bool {
for z := range Zip(x, y) {
if z.Ok1 != z.Ok2 || z.V1 != z.V2 {
return false
}
}
return true
}
Example ¶
package main
import (
"fmt"
"github.com/dashjay/xiter/pkg/xiter"
)
func main() {
seq1 := xiter.FromSlice([]int{1, 2, 3})
seq2 := xiter.FromSlice([]int{11, 22, 33})
zipped := xiter.Zip(seq1, seq2)
out := xiter.ToSlice(zipped)
for _, o := range out {
fmt.Println(o.V1, o.V2)
}
}
Output: 1 11 2 22 3 33
func Zip2 ¶
Zip2 returns an iterator that iterates x and y in parallel, yielding Zipped2 values of successive elements of x and y. If one sequence ends before the other, the iteration continues with Zipped2 values in which either Ok1 or Ok2 is false, depending on which sequence ended first.
Zip2 is a useful building block for adapters that process pairs of sequences. For example, Equal2 can be defined as:
func Equal2[K, V comparable](x, y Seq2[K, V]) bool {
for z := range Zip2(x, y) {
if z.Ok1 != z.Ok2 || z.K1 != z.K2 || z.V1 != z.V2 {
return false
}
}
return true
}
type Seq2 ¶
Seq2 is a sequence of key/value pair provided by an iterator-like function. We made this alias Seq2 to iter.Seq2 for providing a compatible interface in lower go versions.
func Concat2 ¶
Concat2 returns an Seq2 over the concatenation of the given Seq2s. Like Concat but run with Seq2
func Filter2 ¶
Filter2 returns an Seq over seq that only includes the key-value pairs k, v for which f(k, v) is true. Like Filter but run with Seq2
func FromMapKeyAndValues ¶
func FromMapKeyAndValues[K comparable, V any](m map[K]V) Seq2[K, V]
func FromSliceIdx ¶
FromSliceIdx received a slice and returned a Seq2 for this slice, key is index.
func Limit2 ¶
Limit2 returns a Seq over Seq2 that stops after n key-value pairs. Like Limit but run with Seq2
func Map2 ¶
func Map2[KIn, VIn, KOut, VOut any]( f func(KIn, VIn) (KOut, VOut), seq Seq2[KIn, VIn]) Seq2[KOut, VOut]
Map2 returns a Seq2 over the results of applying f to each key-value pair in seq. Like Map but run with Seq2
func Merge2 ¶
Merge2 merges two sequences of key-value pairs ordered by their keys. Pairs appear in the output once for each time they appear in x and once for each time they appear in y. If the two input sequences are not ordered by their keys, the output sequence will not be ordered by its keys, but it will still contain every pair from x and y exactly once.
Merge2 is equivalent to calling MergeFunc2 with cmp.Compare[K] as the ordering function.
func MergeFunc2 ¶
MergeFunc2 merges two sequences of key-value pairs ordered by the function f. Pairs appear in the output once for each time they appear in x and once for each time they appear in y. When pairs with equal keys appear in both sequences, the output contains the pairs from x before the pairs from y. If the two input sequences are not ordered by f, the output sequence will not be ordered by f, but it will still contain every pair from x and y exactly once.
type Zipped ¶
type Zipped[V1, V2 any] struct { V1 V1 Ok1 bool // whether V1 is present (if not, it will be zero) V2 V2 Ok2 bool // whether V2 is present (if not, it will be zero) }
A Zipped is a pair of zipped values, one of which may be missing, drawn from two different sequences.
type Zipped2 ¶
type Zipped2[K1, V1, K2, V2 any] struct { K1 K1 V1 V1 Ok1 bool // whether K1, V1 are present (if not, they will be zero) K2 K2 V2 V2 Ok2 bool // whether K2, V2 are present (if not, they will be zero) }
A Zipped2 is a pair of zipped key-value pairs, one of which may be missing, drawn from two different sequences.