import "github.com/dashjay/xiter"import "github.com/dashjay/xiter/pkg/cmp"- func Compare[T Ordered](x, y T) int
- func Less[T Ordered](x, y T) bool
- func Or[T comparable](vals ...T) T
- type Ordered
func Compare
func Compare[T Ordered](x, y T) intExample
package main
import (
"fmt"
"math"
"github.com/dashjay/xiter/pkg/cmp"
)
func main() {
fmt.Println(cmp.Compare(1, 2))
fmt.Println(cmp.Compare("a", "aa"))
fmt.Println(cmp.Compare(1.5, 1.5))
fmt.Println(cmp.Compare(math.NaN(), 1.0))
}-1
-1
0
-1
func Less
func Less[T Ordered](x, y T) boolExample
package main
import (
"fmt"
"math"
"github.com/dashjay/xiter/pkg/cmp"
)
func main() {
fmt.Println(cmp.Less(1, 2))
fmt.Println(cmp.Less("a", "aa"))
fmt.Println(cmp.Less(1.0, math.NaN()))
fmt.Println(cmp.Less(math.NaN(), 1.0))
}true
true
false
true
func Or
func Or[T comparable](vals ...T) TExample
package main
import (
"fmt"
"github.com/dashjay/xiter/pkg/cmp"
)
func main() {
// Suppose we have some user input
// that may or may not be an empty string
userInput1 := ""
userInput2 := "some text"
fmt.Println(cmp.Or(userInput1, "default"))
fmt.Println(cmp.Or(userInput2, "default"))
fmt.Println(cmp.Or(userInput1, userInput2, "default"))
}default
some text
some text
Example (Sort)
package main
import (
"fmt"
"sort"
"strings"
"github.com/dashjay/xiter/pkg/cmp"
)
type Order struct {
Product string
Customer string
Price float64
}
type Orders []Order
func (o Orders) Len() int {
return len(o)
}
func (o Orders) Less(i, j int) bool {
a, b := o[i], o[j]
if cmp.Or(
strings.Compare(a.Customer, b.Customer),
strings.Compare(a.Product, b.Product),
cmp.Compare(b.Price, a.Price)) < 0 {
return true
} else {
return false
}
}
func (o Orders) Swap(i, j int) {
o[i], o[j] = o[j], o[i]
}
func main() {
orders := []Order{
{"foo", "alice", 1.00},
{"bar", "bob", 3.00},
{"baz", "carol", 4.00},
{"foo", "alice", 2.00},
{"bar", "carol", 1.00},
{"foo", "bob", 4.00},
}
//Sort by customer first, product second, and last by higher price
sort.Sort(Orders(orders))
// wait for the implement of slices.SortFunc
//SortFunc(orders, func(a, b Order) int {
// return cmp.Or(
// strings.Compare(a.Customer, b.Customer),
// strings.Compare(a.Product, b.Product),
// cmp.Compare(b.Price, a.Price),
// )
//})
for _, order := range orders {
fmt.Printf("%s %s %.2f\n", order.Product, order.Customer, order.Price)
}
}foo alice 2.00
foo alice 1.00
bar bob 3.00
foo bob 4.00
bar carol 1.00
baz carol 4.00
type Ordered
type Ordered cmp.Orderedimport "github.com/dashjay/xiter/pkg/optional"Package optional provides a type which can be used to represent a value that may or may not be present like option in Rust.
type O
type O[T any] struct {
// contains filtered or unexported fields
}func Empty
func Empty[T any]() O[T]Empty creates an empty Optional with no value.
func FromValue
func FromValue[T any](v T) O[T]FromValue creates an Optional from a value.
func FromValue2
func FromValue2[T any](v T, ok bool) O[T]FromValue2 creates an Optional from a value and a boolean meaning whether the value is valid.
HINT:
if we have a function defined as fn () (T, bool),
we can use FromValue2(fn()) instead of
if v, ok := fn(); ok { FromValue(v) } else { Empty[T]() }
func (O[T]) Must
func (o O[T]) Must() TMust directly return the value of the Optional.
❌WARNING: Panic if the Optional has no value.
func (O[T]) Ok
func (o O[T]) Ok() boolOk returns whether the Optional has a valid value.
func (O[T]) Ptr
func (o O[T]) Ptr() *TPtr returns a pointer to the value of the Optional. return nil if the Optional has no value.
func (O[T]) ValueOr
func (o O[T]) ValueOr(dft T) TValueOr returns the value of the Optional if it has a valid value, otherwise returns the given default value.
func (O[T]) ValueOrZero
func (o O[T]) ValueOrZero() TValueOrZero returns the value of the Optional if it has a valid value, otherwise returns the zero value of T.
import "github.com/dashjay/xiter/pkg/union"type U2
type U2[T1, T2 any] struct {
T1 T1
T2 T2
}type U3
type U3[T1, T2, T3 any] struct {
T1 T1
T2 T2
T3 T3
}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
- 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 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 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 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 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
func AllFromSeq
func AllFromSeq[T any](seq Seq[T], f func(T) bool) boolAllFromSeq 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) boolAnyFromSeq 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) float64AvgByFromSeq return the average value of all elements from seq, evaluated by f.
func AvgFromSeq
func AvgFromSeq[T constraints.Number](seq Seq[T]) float64AvgFromSeq return the average value of all elements from seq.
func Contains
func Contains[T comparable](seq Seq[T], in T) boolContains return true if v is in seq.
func ContainsAll
func ContainsAll[T comparable](seq Seq[T], in []T) boolContainsAll return true if all elements from seq is in vs.
func ContainsAny
func ContainsAny[T comparable](seq Seq[T], in []T) boolContainsAny return true if any element from seq is in vs.
func ContainsBy
func ContainsBy[T any](seq Seq[T], f func(T) bool) boolContainsBy return true if any element from seq satisfies the condition evaluated by f.
func Count
func Count[T any](seq Seq[T]) intCount return the number of elements in seq.
func Equal
func Equal[V comparable](x, y Seq[V]) boolEqual 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))
}true
false
func Equal2
func Equal2[K, V comparable](x, y Seq2[K, V]) boolEqual2 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) boolEqualFunc 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))
}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) boolEqualFunc2 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 Join
func Join[T ~string](seq Seq[T], sep T) TJoin 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)
}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]) SumReduce 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)
}5050
func Reduce2
func Reduce2[Sum, K, V any](f func(Sum, K, V) Sum, sum Sum, seq Seq2[K, V]) SumReduce2 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 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 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))
}[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))
}[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))
}[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))
}[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))
}[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 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)
}
}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)
}import "github.com/dashjay/xiter/pkg/xslice"- func All[T any](in []T, f func(T) bool) bool
- func Any[T any](in []T, f func(T) bool) bool
- func Avg[T constraints.Number](in []T) float64
- func AvgBy[V any, T constraints.Number](in []V, f func(V) T) float64
- func AvgN[T constraints.Number](inputs ...T) float64
- func Chunk[T any, Slice ~[]T](in Slice, chunkSize int) []Slice
- func ChunkInPlace[T any, Slice ~[]T](in Slice, chunkSize int) []Slice
- func Clone[T any](in []T) []T
- func CloneBy[T any, U any](in []T, f func(T) U) []U
- func Concat[T any](vs ...[]T) []T
- func Contains[T comparable](in []T, v T) bool
- func ContainsAll[T comparable](in []T, v []T) bool
- func ContainsAny[T comparable](in []T, v []T) bool
- func ContainsBy[T any](in []T, f func(T) bool) bool
- func Count[T any](in []T) int
- func Find[T any](in []T, f func(T) bool) (val T, found bool)
- func FindO[T any](in []T, f func(T) bool) optional.O[T]
- func ForEach[T any](in []T, f func(T) bool)
- func ForEachIdx[T any](in []T, f func(idx int, v T) bool)
- func Head[T any](in []T) (v T, hasOne bool)
- func HeadO[T any](in []T) optional.O[T]
- func Join[T ~string](in []T, sep T) T
- func Map[T any, U any](in []T, f func(T) U) []U
- func Max[T constraints.Ordered](in []T) optional.O[T]
- func MaxBy[T constraints.Ordered](in []T, f func(T, T) bool) optional.O[T]
- func MaxN[T constraints.Ordered](in ...T) optional.O[T]
- func Min[T constraints.Ordered](in []T) optional.O[T]
- func MinBy[T constraints.Ordered](in []T, f func(T, T) bool) optional.O[T]
- func MinN[T constraints.Ordered](in ...T) optional.O[T]
- func Repeat[T any, Slice ~[]T](in Slice, count int) Slice
- func RepeatBy[T any](n int, f func(i int) T) []T
- func Replace[T comparable, Slice ~[]T](in Slice, from, to T, count int) []T
- func ReplaceAll[T comparable, Slice ~[]T](in Slice, from, to T) []T
- func Reverse[T any, Slice ~[]T](in Slice)
- func ReverseClone[T any, Slice ~[]T](in Slice) Slice
- func Shuffle[T any, Slice ~[]T](in Slice) Slice
- func ShuffleInPlace[T any, Slice ~[]T](in Slice)
- func Subset[T any, Slice ~[]T](in Slice, start, count int) Slice
- func SubsetInPlace[T any, Slice ~[]T](in Slice, start int, count int) Slice
func All
func All[T any](in []T, f func(T) bool) boolAll returns true if all elements in the slice satisfy the condition provided by f. return false if any element in the slice does not satisfy the condition provided by f.
EXAMPLE:
xslice.All([]int{1, 2, 3}, func(x int) bool { return x > 0 }) 👉 true
xslice.All([]int{-1, 1, 2, 3}, func(x int) bool { return x > 0 }) 👉 false
func Any
func Any[T any](in []T, f func(T) bool) boolAny returns true if any element in the slice satisfy the condition provided by f. return false if none of element in the slice satisfy the condition provided by f.
EXAMPLE:
xslice.Any([]int{0, 1, 2, 3}, func(x int) bool { return x == 0 }) 👉 true
xslice.Any([]int{0, 1, 2, 3}, func(x int) bool { return x == -1 }) 👉 false
func Avg
func Avg[T constraints.Number](in []T) float64Avg returns the average value of the items in slice (float64).
EXAMPLE:
xslice.Avg([]int{1, 2, 3}) 👉 float(2)
xslice.Avg([]int{}) 👉 float(0)
func AvgBy
func AvgBy[V any, T constraints.Number](in []V, f func(V) T) float64AvgBy returns the averaged of each item's value evaluated by f.
EXAMPLE:
xslice.AvgBy([]string{"1", "2", "3"}, func(x string) int {
i, _ := strconv.Atoi(x)
return i
}) 👉 float(2)
func AvgN
func AvgN[T constraints.Number](inputs ...T) float64AvgN returns the average value of the items
EXAMPLE:
xslice.AvgN(1, 2, 3) 👉 float(2)
xslice.AvgN() 👉 float(0)
func Chunk
func Chunk[T any, Slice ~[]T](in Slice, chunkSize int) []SliceChunk returns a new slice with the elements in the slice chunked into smaller slices of the specified size.
EXAMPLE:
xslice.Chunk([]int{1, 2, 3, 4, 5}, 2) 👉 [[1, 2], [3, 4], [5]]
xslice.Chunk([]int{1, 2, 3, 4, 5}, 10) 👉 [[1, 2, 3, 4, 5]]
xslice.Chunk([]int{1, 2, 3, 4, 5}, 0) 👉 []int{}
func ChunkInPlace
func ChunkInPlace[T any, Slice ~[]T](in Slice, chunkSize int) []SliceChunkInPlace returns a new slice with the elements in the slice chunked into smaller slices of the specified size. This function will not copy the elements, has no extra costs. EXAMPLE:
xslice.Chunk([]int{1, 2, 3, 4, 5}, 2) 👉 [[1, 2], [3, 4], [5]]
xslice.Chunk([]int{1, 2, 3, 4, 5}, 10) 👉 [[1, 2, 3, 4, 5]]
xslice.Chunk([]int{1, 2, 3, 4, 5}, 0) 👉 []int{}
func Clone
func Clone[T any](in []T) []TClone returns a copy of the slice.
EXAMPLE:
xslice.Clone([]int{1, 2, 3}) 👉 [1, 2, 3]
func CloneBy
func CloneBy[T any, U any](in []T, f func(T) U) []UCloneBy returns a copy of the slice with the results of applying the given function to every element in this slice.
EXAMPLE:
xslice.CloneBy([]int{1, 2, 3}, func(x int) int { return x * 2 }) 👉 [2, 4, 6]
xslice.CloneBy([]int{1, 2, 3}, strconv.Itoa) 👉 ["1", "2", "3"]
func Concat
func Concat[T any](vs ...[]T) []TConcat concatenates the slices.
EXAMPLE:
xslice.Concat([]int{1, 2, 3}, []int{4, 5, 6}) 👉 [1, 2, 3, 4, 5, 6]
xslice.Concat([]int{1, 2, 3}, []int{}) 👉 [1, 2, 3]
func Contains
func Contains[T comparable](in []T, v T) boolContains returns true if the slice contains the value v.
EXAMPLE:
xslice.Contains([]int{1, 2, 3}, 1) 👉 true
xslice.Contains([]int{-1, 2, 3}, 1) 👉 false
func ContainsAll
func ContainsAll[T comparable](in []T, v []T) boolContainsAll returns true if the slice contains all values in v.
EXAMPLE:
xslice.ContainsAll([]string{"1", "2", "3"}, []string{"1", "2", "3"}) 👉 true
xslice.ContainsAll([]string{"1", "2", "3"}, []string{"1", "99", "1000"}) 👉 false
xslice.ContainsAll([]string{"1", "2", "3"}, []string{}) 👉 true
func ContainsAny
func ContainsAny[T comparable](in []T, v []T) boolContainsAny returns true if the slice contains any value in v.
EXAMPLE:
xslice.ContainsAny([]string{"1", "2", "3"}, []string{"1", "99", "1000"}) 👉 true
xslice.ContainsAny([]string{"1", "2", "3"}, []string{"-1"}) 👉 false
xslice.ContainsAny([]string{"1", "2", "3"}, []string{}) 👉 false
func ContainsBy
func ContainsBy[T any](in []T, f func(T) bool) boolContainsBy returns true if the slice contains the value v evaluated by f.
EXAMPLE:
xslice.ContainsBy([]string{"1", "2", "3"}, func(x string) bool {
i, _ := strconv.Atoi(x)
return i == 1
}) 👉 true
xslice.ContainsBy([]string{"1", "2", "3"}, func(x string) bool {
i, _ := strconv.Atoi(x)
return i == -1
}) 👉 false
func Count
func Count[T any](in []T) intCount returns the number of items in the slice.
EXAMPLE:
xslice.Count([]int{1, 2, 3}) 👉 3
xslice.Count([]int{}) 👉 0
func Find
func Find[T any](in []T, f func(T) bool) (val T, found bool)Find returns the first item in the slice that satisfies the condition provided by f.
EXAMPLE:
xslice.Find([]int{1, 2, 3}, func(x int) bool { return x == 1 }) 👉 1, true
xslice.Find([]int{1, 2, 3}, func(x int) bool { return x == -1 }) 👉 0, false
func FindO
func FindO[T any](in []T, f func(T) bool) optional.O[T]FindO returns the first item in the slice that satisfies the condition provided by f.
EXAMPLE:
xslice.FindO(_range(0, 10), func(x int) bool { return x == 1 }).Must() 👉 1
xslice.FindO(_range(0, 10), func(x int) bool { return x == -1 }).Ok() 👉 false
func ForEach
func ForEach[T any](in []T, f func(T) bool)ForEach iterates over each item in the slice, stop if f returns false.
EXAMPLE:
ForEach([]int{1, 2, 3}, func(x int) bool {
fmt.Println(x)
return true
}
Output:
1
2
3
func ForEachIdx
func ForEachIdx[T any](in []T, f func(idx int, v T) bool)ForEachIdx iterates over each item in the slice, stop if f returns false.
EXAMPLE:
ForEach([]int{1, 2, 3}, func(idx, x int) bool {
fmt.Println(idx, x)
return true
}
Output:
0 1
1 2
2 3
func Head
func Head[T any](in []T) (v T, hasOne bool)Head returns the first item in the slice.
EXAMPLE:
optional.FromValue2(xslice.Head(_range(0, 10))).Must() 👉 0
optional.FromValue2(xslice.Head(_range(0, 0))).Ok() 👉 false
func HeadO
func HeadO[T any](in []T) optional.O[T]HeadO returns the first item in the slice.
EXAMPLE:
xslice.HeadO(_range(0, 10)).Must() 👉 0
xslice.HeadO(_range(0, 0)).Ok() 👉 false
func Join
func Join[T ~string](in []T, sep T) TJoin joins the slice with sep.
EXAMPLE:
xslice.Join([]string{"1", "2", "3"}, ".") 👉 "1.2.3"
xslice.Join([]string{}, ".") 👉 ""
func Map
func Map[T any, U any](in []T, f func(T) U) []UMap returns a new slice with the results of applying the given function to every element in this slice.
EXAMPLE:
xslice.Map([]int{1, 2, 3}, func(x int) int { return x * 2 }) 👉 [2, 4, 6]
xslice.Map([]int{1, 2, 3}, strconv.Itoa) 👉 ["1", "2", "3"]
func Max
func Max[T constraints.Ordered](in []T) optional.O[T]Max returns the maximum value in the slice.
EXAMPLE:
xslice.Max([]int{1, 2, 3}) 👉 3
xslice.Max([]int{}) 👉 0
func MaxBy
func MaxBy[T constraints.Ordered](in []T, f func(T, T) bool) optional.O[T]MaxBy returns the maximum value evaluated by f in the slice.
EXAMPLE:
xslice.MaxBy([]int{1, 2, 3} /*less = */, func(a, b int) bool { return a > b }).Must() 👉 1
func MaxN
func MaxN[T constraints.Ordered](in ...T) optional.O[T]MaxN returns the maximum value in the slice.
EXAMPLE:
xslice.MaxN(1, 2, 3) 👉 3
func Min
func Min[T constraints.Ordered](in []T) optional.O[T]Min returns the minimum value in the slice.
EXAMPLE:
xslice.Min([]int{1, 2, 3}) 👉 1
xslice.Min([]int{}) 👉 0
func MinBy
func MinBy[T constraints.Ordered](in []T, f func(T, T) bool) optional.O[T]MinBy returns the minimum value evaluated by f in the slice.
EXAMPLE:
xslice.MinBy([]int{3, 2, 1} /*less = */, func(a, b int) bool { return a > b }).Must() 👉 3
func MinN
func MinN[T constraints.Ordered](in ...T) optional.O[T]MinN returns the minimum value in the slice.
EXAMPLE:
xslice.MinN(1, 2, 3) 👉 1
func Repeat
func Repeat[T any, Slice ~[]T](in Slice, count int) SliceRepeat returns a new slice with the elements repeated 'count' times.
EXAMPLE:
xslice.Repeat([]int{1, 2, 3}, 3) 👉 [1, 2, 3, 1, 2, 3, 1, 2, 3]
xslice.Repeat([]int{1, 2, 3}, 0) 👉 []int{}
func RepeatBy
func RepeatBy[T any](n int, f func(i int) T) []TRepeatBy returns a new slice with the elements return by f repeated 'count' times.
EXAMPLE:
xslice.RepeatBy(3, func(i int) int { return i }) 👉 [0, 1, 2]
xslice.RepeatBy(3, func(i int) string { return strconv.Itoa(i) }) 👉 []string{"1", "2", "3"}
func Replace
func Replace[T comparable, Slice ~[]T](in Slice, from, to T, count int) []TReplace replaces the count elements in the slice from 'from' to 'to'.
EXAMPLE:
xslice.Replace([]int{1, 2, 3}, 2, 4, 1) 👉 [1, 4, 3]
xslice.Replace([]int{1, 2, 2}, 2, 4, -1) 👉 [1, 4, 4]
func ReplaceAll
func ReplaceAll[T comparable, Slice ~[]T](in Slice, from, to T) []TReplaceAll replaces all elements in the slice from 'from' to 'to'.
EXAMPLE:
xslice.ReplaceAll([]int{1, 2, 3}, 2, 4) 👉 [1, 4, 3]
xslice.ReplaceAll([]int{1, 2, 2}, 2, 4) 👉 [1, 4, 4]
func Reverse
func Reverse[T any, Slice ~[]T](in Slice)Reverse reverses the slice.
EXAMPLE:
xslice.Reverse([]int{1, 2, 3}) 👉 [3, 2, 1]
xslice.Reverse([]int{}) 👉 []int{}
func ReverseClone
func ReverseClone[T any, Slice ~[]T](in Slice) SliceReverseClone reverses the slice.
EXAMPLE:
xslice.ReverseClone([]int{1, 2, 3}) 👉 [3, 2, 1]
xslice.ReverseClone([]int{}) 👉 []int{}
xslice.ReverseClone([]int{3, 2, 1}) 👉 [1, 2, 3]
func Shuffle
func Shuffle[T any, Slice ~[]T](in Slice) SliceShuffle shuffles the slice.
EXAMPLE:
xslice.Shuffle([]int{1, 2, 3}) 👉 [2, 1, 3] (random)
xslice.Shuffle([]int{}) 👉 []int{}
func ShuffleInPlace
func ShuffleInPlace[T any, Slice ~[]T](in Slice)ShuffleInPlace shuffles the slice.
EXAMPLE:
array := []int{1, 2, 3}
xslice.ShuffleInPlace(array) 👉 [2, 1, 3] (random)
func Subset
func Subset[T any, Slice ~[]T](in Slice, start, count int) SliceSubset returns a subset slice from the slice. if start < -1 means that we take subset from right-to-left
EXAMPLE:
xslice.Subset([]int{1, 2, 3}, 0, 2) 👉 [1, 2]
xslice.Subset([]int{1, 2, 3}, -1, 2) 👉 [2, 3]
func SubsetInPlace
func SubsetInPlace[T any, Slice ~[]T](in Slice, start int, count int) SliceSubsetInPlace returns a subset slice copied from the slice. if start < -1 means that we take subset from right-to-left EXAMPLE:
xslice.SubsetInPlace([]int{1, 2, 3}, 0, 2) 👉 [1, 2]
xslice.SubsetInPlace([]int{1, 2, 3}, -1, 2) 👉 [2, 3]
import "github.com/dashjay/xiter/pkg/internal/constraints"Package constraints defined constraints for generics tools
type Float
type Float interface {
// contains filtered or unexported methods
}type Integer
type Integer interface {
// contains filtered or unexported methods
}type Number
type Number interface {
// contains filtered or unexported methods
}type Ordered
type Ordered interface {
// contains filtered or unexported methods
}import "github.com/dashjay/xiter/pkg/internal/xassert"func MustBePositive
func MustBePositive[T constraints.Number](in T)Generated by gomarkdoc