Skip to content

Latest commit

 

History

History
2349 lines (1652 loc) · 57.1 KB

File metadata and controls

2349 lines (1652 loc) · 57.1 KB

xiter

import "github.com/dashjay/xiter"

Index

cmp

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

Index

func Compare

func Compare[T Ordered](x, y T) int
Example

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

Output

-1
-1
0
-1

func Less

func Less[T Ordered](x, y T) bool
Example

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

Output

true
true
false
true

func Or

func Or[T comparable](vals ...T) T
Example

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

Output

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

}

Output

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.Ordered

optional

import "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.

Index

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[T any](v T) O[T]

FromValue creates an Optional from a value.

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() T

Must directly return the value of the Optional.

❌WARNING: Panic if the Optional has no value.

func (O[T]) Ok

func (o O[T]) Ok() bool

Ok returns whether the Optional has a valid value.

func (O[T]) Ptr

func (o O[T]) Ptr() *T

Ptr 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) T

ValueOr 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() T

ValueOrZero returns the value of the Optional if it has a valid value, otherwise returns the zero value of T.

union

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

Index

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
}

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[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[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[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[T constraints.Number](seq Seq[T]) float64

AvgFromSeq return the average value of all elements from seq.

func Contains[T comparable](seq Seq[T], in T) bool

Contains return true if v is in seq.

func ContainsAll[T comparable](seq Seq[T], in []T) bool

ContainsAll return true if all elements from seq is in vs.

func ContainsAny[T comparable](seq Seq[T], in []T) bool

ContainsAny return true if any element from seq is in vs.

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[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[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[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) 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 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[T any](seq Seq[T], n int) (out []T)

ToSliceN pull out n elements from seq.

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

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[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]

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

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

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

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[K comparable, V any](m map[K]V) Seq2[K, V]

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

xslice

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

Index

func All

func All[T any](in []T, f func(T) bool) bool

All 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) bool

Any 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) float64

Avg 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) float64

AvgBy 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) float64

AvgN 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) []Slice

Chunk 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[T any, Slice ~[]T](in Slice, chunkSize int) []Slice

ChunkInPlace 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) []T

Clone 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) []U

CloneBy 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) []T

Concat 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[T comparable](in []T, v T) bool

Contains 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[T comparable](in []T, v []T) bool

ContainsAll 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[T comparable](in []T, v []T) bool

ContainsAny 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[T any](in []T, f func(T) bool) bool

ContainsBy 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) int

Count 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[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) T

Join 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) []U

Map 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) Slice

Repeat 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[T any](n int, f func(i int) T) []T

RepeatBy 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) []T

Replace 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[T comparable, Slice ~[]T](in Slice, from, to T) []T

ReplaceAll 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[T any, Slice ~[]T](in Slice) Slice

ReverseClone 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) Slice

Shuffle shuffles the slice.

EXAMPLE:

xslice.Shuffle([]int{1, 2, 3}) 👉 [2, 1, 3] (random)
xslice.Shuffle([]int{}) 👉 []int{}

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

Subset 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[T any, Slice ~[]T](in Slice, start int, count int) Slice

SubsetInPlace 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]

constraints

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

Package constraints defined constraints for generics tools

Index

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
}

xassert

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

Index

func MustBePositive[T constraints.Number](in T)

Generated by gomarkdoc