xiter

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 15, 2025 License: MIT Imports: 9 Imported by: 0

README

xiter

import "github.com/dashjay/xiter/pkg/xiter"

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

func AllFromSeq[T any](seq Seq[T], f func(T) bool) bool

AllFromSeq return true if all elements from seq satisfy the condition evaluated by f.

func AnyFromSeq

func AnyFromSeq[T any](seq Seq[T], f func(T) bool) bool

AnyFromSeq return true if any elements from seq satisfy the condition evaluated by f.

func At

func At[T any](seq Seq[T], index int) optional.O[T]

At return the element at index from seq.

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

func ContainsBy[T any](seq Seq[T], f func(T) bool) bool

ContainsBy return true if any element from seq satisfies the condition evaluated by f.

func Count

func Count[T any](seq Seq[T]) int

Count return the number of elements in seq.

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

func EqualFunc[V1, V2 any](x Seq[V1], y Seq[V2], f func(V1, V2) bool) bool

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

func Find[T any](seq Seq[T], f func(T) bool) (val T, found bool)

Find return the first element from seq that satisfies the condition evaluated by f with a boolean representing whether it exists.

func FindO

func FindO[T any](seq Seq[T], f func(T) bool) optional.O[T]

FindO return the first element from seq that satisfies the condition evaluated by f.

func ForEach

func ForEach[T any](seq Seq[T], f func(T) bool)

ForEach execute f for each element in seq.

func ForEachIdx

func ForEachIdx[T any](seq Seq[T], f func(idx int, v T) bool)

ForEachIdx execute f for each element in seq with its index.

func Head

func Head[T any](seq Seq[T]) (v T, hasOne bool)

Head return the first element from seq with a boolean representing whether it is at least one element in seq.

func HeadO

func HeadO[T any](seq Seq[T]) optional.O[T]

HeadO return the first element from seq.

func Index

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 Join

func Join[T ~string](seq Seq[T], sep T) T

Join return the concatenation of all elements in seq with sep.

func Max

func Max[T constraints.Ordered](seq Seq[T]) (r optional.O[T])

Max returns the maximum element in seq.

func MaxBy

func MaxBy[T constraints.Ordered](seq Seq[T], less func(T, T) bool) (r optional.O[T])

MaxBy return the maximum element in seq, evaluated by f.

func Min

func Min[T constraints.Ordered](seq Seq[T]) (r optional.O[T])

Min return the minimum element in seq.

func MinBy

func MinBy[T constraints.Ordered](seq Seq[T], less func(T, T) bool) (r optional.O[T])

MinBy return the minimum element in seq, evaluated by f.

func Pull

func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func())

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 Pull2

func Pull2[K, V any](seq Seq2[K, V]) (next func() (K, V, bool), stop func())

func Reduce

func Reduce[Sum, V any](f func(Sum, V) Sum, sum Sum, seq Seq[V]) Sum

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

func Reduce2[Sum, K, V any](f func(Sum, K, V) Sum, sum Sum, seq Seq2[K, V]) Sum

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

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 ToSlice

func ToSlice[T any](seq Seq[T]) (out []T)

ToSlice returns the elements in seq as a slice.

func ToSliceN

func ToSliceN[T any](seq Seq[T], n int) (out []T)

ToSliceN pull out n elements from seq.

func ToSliceSeq2Key

func ToSliceSeq2Key[K, V any](seq Seq2[K, V]) (out []K)

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

func ToSliceSeq2Value[K, V any](seq Seq2[K, V]) (out []V)

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)

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.

type Seq[V any] iter.Seq[V]

func Chunk
func Chunk[T any](seq Seq[T], n int) Seq[[]T]

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
func Concat[V any](seqs ...Seq[V]) Seq[V]

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
func Filter[V any](f func(V) bool, seq Seq[V]) Seq[V]

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 FromSlice
func FromSlice[T any](in []T) Seq[T]

FromSlice received a slice and returned a Seq for this slice.

func FromSliceReverse
func FromSliceReverse[T any, Slice ~[]T](in Slice) Seq[T]

func FromSliceShuffle
func FromSliceShuffle[T any](in []T) Seq[T]

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
func Limit[V any](seq Seq[V], n int) Seq[V]

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
func Map[In, Out any](f func(In) Out, seq Seq[In]) Seq[Out]

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
func Merge[V cmp.Ordered](x, y Seq[V]) Seq[V]

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
func MergeFunc[V any](x, y Seq[V], f func(V, V) int) Seq[V]

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 Repeat
func Repeat[T any](seq Seq[T], count int) Seq[T]

Repeat return a seq that repeat seq for count times.

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 Reverse
func Reverse[T any](seq Seq[T]) Seq[T]

Reverse return a reversed seq.

func Seq2KeyToSeq
func Seq2KeyToSeq[K, V any](in Seq2[K, V]) Seq[K]

func Seq2ToSeqUnion
func Seq2ToSeqUnion[K, V any](seq Seq2[K, V]) Seq[union.U2[K, V]]

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 Seq2ValueToSeq[K, V any](in Seq2[K, V]) Seq[V]

func Skip
func Skip[T any](seq Seq[T], n int) Seq[T]

Skip return a seq that skip n elements from seq.

func Zip
func Zip[V1, V2 any](x Seq[V1], y Seq[V2]) Seq[Zipped[V1, V2]]

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
func Zip2[K1, V1, K2, V2 any](x Seq2[K1, V1], y Seq2[K2, V2]) Seq[Zipped2[K1, V1, K2, V2]]

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.

type Seq2[K, V any] iter.Seq2[K, V]

func Concat2
func Concat2[K, V any](seqs ...Seq2[K, V]) Seq2[K, V]

Concat2 returns an Seq2 over the concatenation of the given Seq2s. Like Concat but run with Seq2

func Filter2
func Filter2[K, V any](f func(K, V) bool, seq Seq2[K, V]) Seq2[K, V]

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
func FromSliceIdx[T any](in []T) Seq2[int, T]

FromSliceIdx received a slice and returned a Seq2 for this slice, key is index.

func Limit2
func Limit2[K, V any](seq Seq2[K, V], n int) Seq2[K, V]

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
func Merge2[K cmp.Ordered, V any](x, y Seq2[K, V]) Seq2[K, V]

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
func MergeFunc2[K, V any](x, y Seq2[K, V], f func(K, K) int) Seq2[K, V]

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

A Zipped is a pair of zipped values, one of which may be missing, drawn from two different sequences.

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)
}

type Zipped2

A Zipped2 is a pair of zipped key-value pairs, one of which may be missing, drawn from two different sequences.

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)
}

Generated by gomarkdoc

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

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AllFromSeq

func AllFromSeq[T any](seq Seq[T], f func(T) bool) bool

AllFromSeq return true if all elements from seq satisfy the condition evaluated by f.

func AnyFromSeq

func AnyFromSeq[T any](seq Seq[T], f func(T) bool) bool

AnyFromSeq return true if any elements from seq satisfy the condition evaluated by f.

func At

func At[T any](seq Seq[T], index int) optional.O[T]

At return the element at index from seq.

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

func ContainsBy[T any](seq Seq[T], f func(T) bool) bool

ContainsBy return true if any element from seq satisfies the condition evaluated by f.

func Count

func Count[T any](seq Seq[T]) int

Count return the number of elements in seq.

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

func EqualFunc[V1, V2 any](x Seq[V1], y Seq[V2], f func(V1, V2) bool) bool

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

func Find[T any](seq Seq[T], f func(T) bool) (val T, found bool)

Find return the first element from seq that satisfies the condition evaluated by f with a boolean representing whether it exists.

func FindO

func FindO[T any](seq Seq[T], f func(T) bool) optional.O[T]

FindO return the first element from seq that satisfies the condition evaluated by f.

func ForEach

func ForEach[T any](seq Seq[T], f func(T) bool)

ForEach execute f for each element in seq.

func ForEachIdx

func ForEachIdx[T any](seq Seq[T], f func(idx int, v T) bool)

ForEachIdx execute f for each element in seq with its index.

func Head[T any](seq Seq[T]) (v T, hasOne bool)

Head return the first element from seq with a boolean representing whether it is at least one element in seq.

func HeadO

func HeadO[T any](seq Seq[T]) optional.O[T]

HeadO return the first element from 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 Join

func Join[T ~string](seq Seq[T], sep T) T

Join return the concatenation of all elements in seq with sep.

func Max

func Max[T constraints.Ordered](seq Seq[T]) (r optional.O[T])

Max returns the maximum element in seq.

func MaxBy

func MaxBy[T constraints.Ordered](seq Seq[T], less func(T, T) bool) (r optional.O[T])

MaxBy return the maximum element in seq, evaluated by f.

func Min

func Min[T constraints.Ordered](seq Seq[T]) (r optional.O[T])

Min return the minimum element in seq.

func MinBy

func MinBy[T constraints.Ordered](seq Seq[T], less func(T, T) bool) (r optional.O[T])

MinBy return the minimum element in seq, evaluated by f.

func Pull

func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func())

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 Pull2

func Pull2[K, V any](seq Seq2[K, V]) (next func() (K, V, bool), stop func())

func Reduce

func Reduce[Sum, V any](f func(Sum, V) Sum, sum Sum, seq Seq[V]) Sum

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

func Reduce2[Sum, K, V any](f func(Sum, K, V) Sum, sum Sum, seq Seq2[K, V]) Sum

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 ToSlice

func ToSlice[T any](seq Seq[T]) (out []T)

ToSlice returns the elements in seq as a slice.

func ToSliceN

func ToSliceN[T any](seq Seq[T], n int) (out []T)

ToSliceN pull out n elements from seq.

func ToSliceSeq2Key

func ToSliceSeq2Key[K, V any](seq Seq2[K, V]) (out []K)

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

func ToSliceSeq2Value[K, V any](seq Seq2[K, V]) (out []V)

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

type Seq[V any] iter.Seq[V]

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

func Chunk[T any](seq Seq[T], n int) Seq[[]T]

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

func Concat[V any](seqs ...Seq[V]) Seq[V]

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

func Filter[V any](f func(V) bool, seq Seq[V]) Seq[V]

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 FromSlice

func FromSlice[T any](in []T) Seq[T]

FromSlice received a slice and returned a Seq for this slice.

func FromSliceReverse

func FromSliceReverse[T any, Slice ~[]T](in Slice) Seq[T]

func FromSliceShuffle

func FromSliceShuffle[T any](in []T) Seq[T]

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

func Limit[V any](seq Seq[V], n int) Seq[V]

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

func Map[In, Out any](f func(In) Out, seq Seq[In]) Seq[Out]

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

func Merge[V cmp.Ordered](x, y Seq[V]) Seq[V]

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

func MergeFunc[V any](x, y Seq[V], f func(V, V) int) Seq[V]

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 Repeat

func Repeat[T any](seq Seq[T], count int) Seq[T]

Repeat return a seq that repeat seq for count times.

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 Reverse

func Reverse[T any](seq Seq[T]) Seq[T]

Reverse return a reversed seq.

func Seq2KeyToSeq

func Seq2KeyToSeq[K, V any](in Seq2[K, V]) Seq[K]

func Seq2ToSeqUnion added in v0.0.2

func Seq2ToSeqUnion[K, V any](seq Seq2[K, V]) Seq[union.U2[K, V]]

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 Seq2ValueToSeq[K, V any](in Seq2[K, V]) Seq[V]

func Skip

func Skip[T any](seq Seq[T], n int) Seq[T]

Skip return a seq that skip n elements from seq.

func Zip

func Zip[V1, V2 any](x Seq[V1], y Seq[V2]) Seq[Zipped[V1, V2]]

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

func Zip2[K1, V1, K2, V2 any](x Seq2[K1, V1], y Seq2[K2, V2]) Seq[Zipped2[K1, V1, K2, V2]]

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

type Seq2[K, V any] iter.Seq2[K, V]

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

func Concat2[K, V any](seqs ...Seq2[K, V]) Seq2[K, V]

Concat2 returns an Seq2 over the concatenation of the given Seq2s. Like Concat but run with Seq2

func Filter2

func Filter2[K, V any](f func(K, V) bool, seq Seq2[K, V]) Seq2[K, V]

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

func FromSliceIdx[T any](in []T) Seq2[int, T]

FromSliceIdx received a slice and returned a Seq2 for this slice, key is index.

func Limit2

func Limit2[K, V any](seq Seq2[K, V], n int) Seq2[K, V]

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

func Merge2[K cmp.Ordered, V any](x, y Seq2[K, V]) Seq2[K, V]

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

func MergeFunc2[K, V any](x, y Seq2[K, V], f func(K, K) int) Seq2[K, V]

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL