gloop

package module
v0.0.0-...-133bc75 Latest Latest
Warning

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

Go to latest
Published: Nov 15, 2024 License: MIT Imports: 9 Imported by: 0

README

Genocide Watch

gloop logo

gloop is a Go utility library for convenient looping using Go's range-over-func feature.

Go Reference Tests Coverage Go Report Card License

Installation

Install gloop using the go get command:

go get github.com/alvii147/gloop

[!NOTE] Go version 1.23+ required as older versions don't offer the range-over-func feature.

Usage

Once installed, gloop can be imported and used directly in your project:

package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	for seq := range gloop.Permutations(gloop.String("CAT"), 3) {
		perm := gloop.ToString(seq)
		fmt.Println(perm)
	}
}

This ranges over and outputs all permutations of CAT:

CAT
CTA
ACT
ATC
TCA
TAC

See more specific documentation and examples in the features section below.

Features

Generators

  • Interval allows looping over values in a given interval of a given step size.
  • Linspace allows looping over evenly spaced values within a given interval. n must be greater than 1.
  • RandomNormal allows looping over a given number of random values drawn from a Gaussian distribution. The size must not be negative and the standard deviation must be positive.
  • RandomUniform allows looping over a given number of random values drawn from a uniform distribution. The size must not be negative.

Scalar Iterators

  • Chain allows looping over multiple iter.Seq sequences.
  • Chain2 allows looping over multiple iter.Seq2 sequences.
  • Channel allows looping over values from a given channel. The values are consumed from the channel.
  • Collect allows looping over a given set of values.
  • Enumerate allows looping over an iter.Seq sequence with an index, converting it to an iter.Seq2 sequence.
  • Filter runs a given function on each value from an iter.Seq sequence and allows looping over values for which the function returns true.
  • Filter2 runs a given function on each value from an iter.Seq2 sequence and allows looping over values for which the function returns true.
  • Keys allows looping over an iter.Seq2, converting it to an iter.Seq sequence by discarding the value.
  • KeyValue converts an iter.Seq sequence of [KeyValuePair] values to an iter.Seq2 sequence.
  • KeyValue2 converts an iter.Seq2 sequence to an iter.Seq sequence of [KeyValuePair] values.
  • List allows looping over a given container/list.List.
  • Map allows looping over keys and values in a map.
  • Reverse allows looping over an iter.Seq sequence in order of descending index.
  • Reverse2 allows looping over an iter.Seq2 sequence in order of descending index.
  • Slice allows looping over a given slice.
  • Sort allows looping over an iter.Seq sequence in sorted order.
  • SortByComparison allows looping over an iter.Seq sequence in sorted order using a comparison function.
  • SortByComparison2 allows looping over an iter.Seq2 sequence in sorted order using a comparison function.
  • SortByRank allows looping over an iter.Seq sequence in sorted order using a ranking function.
  • SortByRank2 allows looping over an iter.Seq2 sequence in sorted order using a ranking function.
  • String allows looping over the runes in a given string.
  • Transform runs a given function on each value over an iter.Seq sequence and allows looping over the returned values.
  • Transform2 runs a given function on each key and value over an iter.Seq2 sequence and allows looping over the returned values.
  • Values allows looping over an iter.Seq2 and converting it to an iter.Seq sequence by discarding the key.
  • Zip allows looping over two iter.Seq sequences in pairs.
  • Zip2 allows looping over two iter.Seq2 sequences in pairs.

Vector Iterators

  • Batch allows looping over an iter.Seq sequence in batches of a given size. The batch size must be positive.
  • Batch2 allows looping over an iter.Seq2 sequence in batches of a given size. The batch size must be positive.
  • CartesianProduct allows looping over the Cartesian product of a given size for an iter.Seq sequence. The size must be positive.
  • CartesianProduct2 allows looping over the Cartesian product of a given size for an iter.Seq2 sequence. The size must be positive.
  • Combinations allows looping over all combinations of a given size for an iter.Seq sequence. The size must be positive.
  • Combinations2 allows looping over all combinations of a given size for an iter.Seq2 sequence. The size must be positive.
  • Permutations allows looping over all permutations of a given size for an iter.Seq sequence. The size must be positive.
  • Permutations2 allows looping over all permutations of a given size for an iter.Seq2 sequence. The size must be positive.
  • Window allows looping over an iter.Seq sequence in sliding windows of a given size.
  • Window2 allows looping over an iter.Seq2 sequence in sliding windows of a given size.
  • ZipN allows looping over multiple iter.Seq sequences simultaneously.
  • ZipN2 allows looping over multiple iter.Seq2 sequences simultaneously.

Aggregators

Miscellaneous

  • DeferLoop allows looping over an iter.Seq sequence, yielding a defer function that can register another function to be executed at the end of the currently running loop. If multiple functions are registered, they are executed in FIFO order.
  • Parallelize runs a function on each value in an iter.Seq sequence on separate goroutines.
  • Parallelize2 runs a function on each value in an iter.Seq2 sequence on separate goroutines.

Contributing

All contributions are welcome! Please see CONTRIBUTING.md for contribution guidelines.

Documentation

Overview

Package gloop is a Go utility library for convenient looping using Go's range-over-func feature.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func All

func All(seq iter.Seq[bool]) bool

All computes whether or not all values in an iter.Seq sequence are true.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	allTrue := []bool{true, true, true}
	someTrue := []bool{true, false, true}
	allFalse := []bool{false, false, false}

	fmt.Println(gloop.All(gloop.Slice(allTrue)))
	fmt.Println(gloop.All(gloop.Slice(someTrue)))
	fmt.Println(gloop.All(gloop.Slice(allFalse)))
}
Output:

true
false
false

func Any

func Any(seq iter.Seq[bool]) bool

Any computes whether or not any value in an iter.Seq sequence is true.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	allTrue := []bool{true, true, true}
	someTrue := []bool{true, false, true}
	allFalse := []bool{false, false, false}

	fmt.Println(gloop.Any(gloop.Slice(allTrue)))
	fmt.Println(gloop.Any(gloop.Slice(someTrue)))
	fmt.Println(gloop.Any(gloop.Slice(allFalse)))
}
Output:

true
true
false

func Batch

func Batch[V any](seq iter.Seq[V], size int) iter.Seq[iter.Seq[V]]

Batch allows looping over an iter.Seq sequence in batches of a given size. The batch size must be positive.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4, 1, 5, 9, 2, 6, 5}
	for seq := range gloop.Batch(gloop.Slice(values), 3) {
		batch := gloop.ToSlice(seq)
		fmt.Println(batch)
	}
}
Output:

[3 1 4]
[1 5 9]
[2 6 5]

func Batch2

func Batch2[K, V any](seq iter.Seq2[K, V], size int) iter.Seq[iter.Seq2[K, V]]

Batch2 allows looping over an iter.Seq2 sequence in batches of a given size. The batch size must be positive.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []string{"CAT", "DOG", "MOUSE", "CHICKEN", "BUNNY", "BEAR"}
	for seq := range gloop.Batch2(gloop.Enumerate(gloop.Slice(values)), 3) {
		batchKeys, batchValues := gloop.ToSlice2(seq)
		fmt.Println(batchKeys, batchValues)
	}
}
Output:

[0 1 2] [CAT DOG MOUSE]
[3 4 5] [CHICKEN BUNNY BEAR]

func CartesianProduct

func CartesianProduct[V any](seq iter.Seq[V], size int) iter.Seq[iter.Seq[V]]

CartesianProduct allows looping over the Cartesian product of a given size for an iter.Seq sequence. The size must be positive.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	s := "CAT"
	for seq := range gloop.CartesianProduct(gloop.String(s), 2) {
		product := gloop.ToString(seq)
		fmt.Println(product)
	}
}
Output:

CC
CA
CT
AC
AA
AT
TC
TA
TT

func CartesianProduct2

func CartesianProduct2[K, V any](seq iter.Seq2[K, V], size int) iter.Seq[iter.Seq2[K, V]]

CartesianProduct2 allows looping over the Cartesian product of a given size for an iter.Seq2 sequence. The size must be positive.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	m := map[string]int{
		"CAT": 3,
		"DOG": 1,
	}
	for seq := range gloop.CartesianProduct2(gloop.Map(m), 2) {
		productKeys, productValues := gloop.ToSlice2(seq)
		fmt.Println(productKeys, productValues)
	}
}
Output:

[CAT CAT] [3 3]
[CAT DOG] [3 1]
[DOG CAT] [1 3]
[DOG DOG] [1 1]

func Chain

func Chain[V any](seqs ...iter.Seq[V]) iter.Seq[V]

Chain allows looping over multiple iter.Seq sequences.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values1 := []int{3, 1, 4}
	values2 := []int{1, 6}
	for i := range gloop.Chain(gloop.Slice(values1), gloop.Slice(values2)) {
		fmt.Println(i)
	}
}
Output:

3
1
4
1
6

func Chain2

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

Chain2 allows looping over multiple iter.Seq2 sequences.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	m1 := map[string]int{
		"CAT": 3,
		"DOG": 1,
	}

	m2 := map[string]int{
		"MOUSE": 4,
	}

	for key, value := range gloop.Chain2(gloop.Map(m1), gloop.Map(m2)) {
		fmt.Println(key, value)
	}
}
Output:

CAT 3
DOG 1
MOUSE 4

func Channel

func Channel[V any](ch <-chan V) iter.Seq[V]

Channel allows looping over values from a given channel. The values are consumed from the channel.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	ch := make(chan string)
	go func() {
		ch <- "CAT"
		ch <- "DOG"
		ch <- "MOUSE"
		close(ch)
	}()

	for i := range gloop.Channel(ch) {
		fmt.Println(i)
	}
}
Output:

CAT
DOG
MOUSE

func Collect

func Collect[V any](values ...V) iter.Seq[V]

Collect allows looping over a given set of values.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	for i := range gloop.Collect(3, 1, 4) {
		fmt.Println(i)
	}
}
Output:

3
1
4

func Combinations

func Combinations[V any](seq iter.Seq[V], size int) iter.Seq[iter.Seq[V]]

Combinations allows looping over all combinations of a given size for an iter.Seq sequence. The size must be positive.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	s := "CAT"
	for seq := range gloop.Combinations(gloop.String(s), 2) {
		comb := gloop.ToString(seq)
		fmt.Println(comb)
	}
}
Output:

CA
CT
AT

func Combinations2

func Combinations2[K, V any](seq iter.Seq2[K, V], size int) iter.Seq[iter.Seq2[K, V]]

Combinations2 allows looping over all combinations of a given size for an iter.Seq2 sequence. The size must be positive.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	m := map[string]int{
		"CAT":   3,
		"DOG":   1,
		"MOUSE": 4,
	}
	for seq := range gloop.Combinations2(gloop.Map(m), 2) {
		combKeys, combValues := gloop.ToSlice2(seq)
		fmt.Println(combKeys, combValues)
	}
}
Output:

[CAT DOG] [3 1]
[CAT MOUSE] [3 4]
[DOG MOUSE] [1 4]

func DeferLoop

func DeferLoop[V any](seq iter.Seq[V]) iter.Seq2[V, DeferLoopFunc]

DeferLoop allows looping over an iter.Seq sequence, yielding a defer function that can register another function to be executed at the end of the currently running loop. If multiple functions are registered, they are executed in FIFO order.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4}
	for i, deferLoop := range gloop.DeferLoop(gloop.Slice(values)) {
		deferLoop(func() {
			fmt.Println("defer loop", i)
		})

		fmt.Println("regular loop", i)
	}
}
Output:

regular loop 3
defer loop 3
regular loop 1
defer loop 1
regular loop 4
defer loop 4

func Enumerate

func Enumerate[V any](seq iter.Seq[V]) iter.Seq2[int, V]

Enumerate allows looping over an iter.Seq sequence with an index, converting it to an iter.Seq2 sequence.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	ch := make(chan int)
	go func() {
		ch <- 3
		ch <- 1
		ch <- 4
		close(ch)
	}()

	for i, value := range gloop.Enumerate(gloop.Channel(ch)) {
		fmt.Println(i, value)
	}
}
Output:

0 3
1 1
2 4

func Equal

func Equal[V comparable](seq1 iter.Seq[V], seq2 iter.Seq[V]) bool

Equal checks if two given iter.Seq sequences are exactly equal in contents and order.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values1 := []int{3, 1, 4}
	values2 := []int{3, 1, -4}
	values3 := []int{3, 1, 4}

	fmt.Println(gloop.Equal(gloop.Slice(values1), gloop.Slice(values2)))
	fmt.Println(gloop.Equal(gloop.Slice(values1), gloop.Slice(values3)))
}
Output:

false
true

func Equal2

func Equal2[K, V comparable](seq1 iter.Seq2[K, V], seq2 iter.Seq2[K, V]) bool

Equal2 checks if two given iter.Seq2 sequences are exactly equal in contents and order.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq1 := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("MOUSE", 4)
	}

	seq2 := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("CHICKEN", 4)
	}

	seq3 := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("MOUSE", 4)
	}

	fmt.Println(gloop.Equal2(seq1, seq2))
	fmt.Println(gloop.Equal2(seq1, seq3))
}
Output:

false
true

func Equivalent

func Equivalent[V comparable](seq1 iter.Seq[V], seq2 iter.Seq[V]) bool

Equivalent checks if two given iter.Seq sequences are equal in contents, ignoring order.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values1 := []int{3, 1, 4}
	values2 := []int{3, 1, -4}
	values3 := []int{3, 4, 1}

	fmt.Println(gloop.Equivalent(gloop.Slice(values1), gloop.Slice(values2)))
	fmt.Println(gloop.Equivalent(gloop.Slice(values1), gloop.Slice(values3)))
}
Output:

false
true

func Equivalent2

func Equivalent2[K, V comparable](seq1 iter.Seq2[K, V], seq2 iter.Seq2[K, V]) bool

Equivalent2 checks if two given iter.Seq2 sequences are equal in contents, ignoring order.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq1 := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("MOUSE", 4)
	}

	seq2 := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("CHICKEN", 4)
	}

	seq3 := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("MOUSE", 4)
		yield("DOG", 1)
	}

	fmt.Println(gloop.Equivalent2(seq1, seq2))
	fmt.Println(gloop.Equivalent2(seq1, seq3))
}
Output:

false
true

func Filter

func Filter[V any](seq iter.Seq[V], f FilterFunc[V]) iter.Seq[V]

Filter runs a given function on each value from an iter.Seq sequence and allows looping over values for which the function returns true.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	isOdd := func(i int) bool {
		return i%2 == 1
	}

	values := []int{3, 1, 4}
	for i := range gloop.Filter(gloop.Slice(values), isOdd) {
		fmt.Println(i)
	}
}
Output:

3
1

func Filter2

func Filter2[K, V any](seq iter.Seq2[K, V], f Filter2Func[K, V]) iter.Seq2[K, V]

Filter2 runs a given function on each value from an iter.Seq2 sequence and allows looping over values for which the function returns true.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	isProductPositive := func(i, j int) bool {
		return i*j >= 0
	}

	m := map[int]int{
		-3: 3,
		-1: -1,
		4:  4,
	}

	for i, j := range gloop.Filter2(gloop.Map(m), isProductPositive) {
		fmt.Println(i, j)
	}
}
Output:

-1 -1
4 4

func Fold

func Fold[A, V any](
	seq iter.Seq[V],
	f FoldFunc[A, V],
	opts ...FoldOptionFunc[A],
) A

Fold runs a given function on each value from an iter.Seq sequence and accumulates the result into a single value.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	add := func(a, b int) int {
		return a + b
	}

	values := []int{3, 1, 4}
	sum := gloop.Fold(gloop.Slice(values), add)
	fmt.Println(sum)
}
Output:

8

func Fold2

func Fold2[A, K, V any](
	seq iter.Seq2[K, V],
	f Fold2Func[A, K, V],
	opts ...FoldOptionFunc[A],
) A

Fold2 runs a given function on each value from an iter.Seq2 sequence and accumulates the result into a single value.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	addKeyValueProduct := func(acc, key, value int) int {
		return acc + (key * value)
	}

	m := map[int]int{
		3: 1,
		1: 5,
		4: 9,
	}

	sumOfProducts := gloop.Fold2(gloop.Map(m), addKeyValueProduct)
	fmt.Println(sumOfProducts)
}
Output:

44

func Interval

func Interval[N Number](
	start N,
	stop N,
	step N,
	opts ...IntervalOptionFunc,
) iter.Seq[N]

Interval allows looping over values in a given interval of a given step size.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	for i := range gloop.Interval(3, 9, 2) {
		fmt.Println(i)
	}
}
Output:

3
5
7

func KeyValue

func KeyValue[K, V any](seq iter.Seq[KeyValuePair[K, V]]) iter.Seq2[K, V]

KeyValue converts an iter.Seq sequence of KeyValuePair values to an iter.Seq2 sequence.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	pairs := []gloop.KeyValuePair[string, int]{
		{
			Key:   "CAT",
			Value: 3,
		},
		{
			Key:   "DOG",
			Value: 1,
		},
		{
			Key:   "MOUSE",
			Value: 4,
		},
	}

	for key, value := range gloop.KeyValue(gloop.Slice(pairs)) {
		fmt.Println(key, value)
	}
}
Output:

CAT 3
DOG 1
MOUSE 4

func KeyValue2

func KeyValue2[K, V any](seq iter.Seq2[K, V]) iter.Seq[KeyValuePair[K, V]]

KeyValue2 converts an iter.Seq2 sequence to an iter.Seq sequence of KeyValuePair values.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	m := map[string]int{
		"CAT":   3,
		"DOG":   1,
		"MOUSE": 4,
	}

	for pair := range gloop.KeyValue2(gloop.Map(m)) {
		fmt.Println(pair.Key, pair.Value)
	}
}
Output:

CAT 3
DOG 1
MOUSE 4

func Keys

func Keys[K, V any](seq iter.Seq2[K, V]) iter.Seq[K]

Keys allows looping over an iter.Seq2, converting it to an iter.Seq sequence by discarding the value.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	m := map[string]int{
		"CAT":   3,
		"DOG":   1,
		"MOUSE": 4,
	}

	for key := range gloop.Keys(gloop.Map(m)) {
		fmt.Println(key)
	}
}
Output:

CAT
DOG
MOUSE

func Linspace

func Linspace[N Number](
	start N,
	stop N,
	n int,
	opts ...LinspaceOptionFunc,
) iter.Seq[float64]

Linspace allows looping over evenly spaced values within a given interval. n must be greater than 1.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	for i := range gloop.Linspace(2, 3, 5) {
		fmt.Println(i)
	}
}
Output:

2
2.25
2.5
2.75

func List

func List(l *list.List) iter.Seq[*list.Element]

List allows looping over a given container/list.List.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	l := list.New()
	l.PushBack(3)
	l.PushBack(1)
	l.PushBack(4)

	for elem := range gloop.List(l) {
		fmt.Println(elem.Value)
	}
}
Output:

3
1
4

func Map

func Map[K comparable, V any](m map[K]V) iter.Seq2[K, V]

Map allows looping over keys and values in a map.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	m := map[string]int{
		"CAT":   3,
		"DOG":   1,
		"MOUSE": 4,
	}

	for key, value := range gloop.Map(m) {
		fmt.Println(key, value)
	}
}
Output:

CAT 3
DOG 1
MOUSE 4

func Max

func Max[V cmp.Ordered](seq iter.Seq[V]) V

Max computes the maximum value over an iter.Seq sequence.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4, 2}
	maxValue := gloop.Max(gloop.Slice(values))
	fmt.Println(maxValue)
}
Output:

4

func MaxByComparison

func MaxByComparison[V any](
	seq iter.Seq[V],
	less SortByComparisonFunc[V],
) V

MaxByComparison computes the maximum value over an iter.Seq sequence using a comparison function.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	compareStringLens := func(s1, s2 string) bool {
		return len(s1) < len(s2)
	}

	values := []string{"CAT", "MOUSE", "CHICKEN"}
	maxValue := gloop.MaxByComparison(gloop.Slice(values), compareStringLens)
	fmt.Println(maxValue)
}
Output:

CHICKEN

func MaxByComparison2

func MaxByComparison2[K, V any](
	seq iter.Seq2[K, V],
	less MinByComparison2Func[K, V],
) (K, V)

MaxByComparison2 computes the maximum key and value over an iter.Seq2 sequence using a comparison function.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	compareKeyValueProducts := func(k1, v1, k2, v2 int) bool {
		return k1*v1 < k2*v2
	}

	m := map[int]int{
		3: 1,
		1: 5,
		4: 9,
	}

	maxKey, maxValue := gloop.MaxByComparison2(gloop.Map(m), compareKeyValueProducts)
	fmt.Println(maxKey, maxValue)
}
Output:

4 9

func MaxByRank

func MaxByRank[V any, R cmp.Ordered](
	seq iter.Seq[V],
	rank MinByRankFunc[V, R],
) V

MaxByRank computes the maximum value over an iter.Seq sequence using a ranking function.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	getStringLen := func(s string) int {
		return len(s)
	}

	values := []string{"CAT", "MOUSE", "CHICKEN"}
	maxValue := gloop.MaxByRank(gloop.Slice(values), getStringLen)
	fmt.Println(maxValue)
}
Output:

CHICKEN

func MaxByRank2

func MaxByRank2[K, V any, R cmp.Ordered](
	seq iter.Seq2[K, V],
	rank MinByRank2Func[K, V, R],
) (K, V)

MaxByRank2 computes the maximum value over an iter.Seq2 sequence using a ranking function.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	getKeyValueProduct := func(k, v int) int {
		return k * v
	}

	m := map[int]int{
		3: 1,
		1: 5,
		4: 9,
	}

	maxKey, maxValue := gloop.MaxByRank2(gloop.Map(m), getKeyValueProduct)
	fmt.Println(maxKey, maxValue)
}
Output:

4 9

func Mean

func Mean[V Number](seq iter.Seq[V]) float64

Mean computes the mean value over an iter.Seq sequence.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4, 2}
	mean := gloop.Mean(gloop.Slice(values))
	fmt.Println(mean)
}
Output:

2.5

func Min

func Min[V cmp.Ordered](seq iter.Seq[V]) V

Min computes the minimum value over an iter.Seq sequence.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4, 2}
	minValue := gloop.Min(gloop.Slice(values))
	fmt.Println(minValue)
}
Output:

1

func MinByComparison

func MinByComparison[V any](
	seq iter.Seq[V],
	less SortByComparisonFunc[V],
) V

MinByComparison computes the minimum value over an iter.Seq sequence using a comparison function.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	compareStringLens := func(s1, s2 string) bool {
		return len(s1) < len(s2)
	}

	values := []string{"CAT", "MOUSE", "CHICKEN"}
	minValue := gloop.MinByComparison(gloop.Slice(values), compareStringLens)
	fmt.Println(minValue)
}
Output:

CAT

func MinByComparison2

func MinByComparison2[K, V any](
	seq iter.Seq2[K, V],
	less MinByComparison2Func[K, V],
) (K, V)

MinByComparison2 computes the minimum key and value over an iter.Seq2 sequence using a comparison function.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	compareKeyValueProducts := func(k1, v1, k2, v2 int) bool {
		return k1*v1 < k2*v2
	}

	m := map[int]int{
		3: 1,
		1: 5,
		4: 9,
	}

	minKey, minValue := gloop.MinByComparison2(gloop.Map(m), compareKeyValueProducts)
	fmt.Println(minKey, minValue)
}
Output:

3 1

func MinByRank

func MinByRank[V any, R cmp.Ordered](
	seq iter.Seq[V],
	rank MinByRankFunc[V, R],
) V

MinByRank computes the minimum value over an iter.Seq sequence using a ranking function.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	getStringLen := func(s string) int {
		return len(s)
	}

	values := []string{"CAT", "MOUSE", "CHICKEN"}
	minValue := gloop.MinByRank(gloop.Slice(values), getStringLen)
	fmt.Println(minValue)
}
Output:

CAT

func MinByRank2

func MinByRank2[K, V any, R cmp.Ordered](
	seq iter.Seq2[K, V],
	rank MinByRank2Func[K, V, R],
) (K, V)

MinByRank2 computes the minimum value over an iter.Seq2 sequence using a ranking function.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	getKeyValueProduct := func(k, v int) int {
		return k * v
	}

	m := map[int]int{
		3: 1,
		1: 5,
		4: 9,
	}

	minKey, minValue := gloop.MinByRank2(gloop.Map(m), getKeyValueProduct)
	fmt.Println(minKey, minValue)
}
Output:

3 1

func Parallelize

func Parallelize[V any](
	seq iter.Seq[V],
	f ParallelizeFunc[V],
	opts ...ParallelizeOptionFunc,
)

Parallelize runs a function on each value in an iter.Seq sequence on separate goroutines.

Example
package main

import (
	"fmt"
	"time"

	"github.com/alvii147/gloop"
)

func main() {
	printlnWithDelay := func(s string) {
		time.Sleep(time.Second)
		fmt.Println(s)
	}

	values := []string{"CAT", "DOG", "MOUSE"}
	timeElaped := time.Now()

	gloop.Parallelize(gloop.Slice(values), printlnWithDelay)
	fmt.Println("Time Elapsed", time.Since(timeElaped))
}
Output:

DOG
MOUSE
CAT
Time Elapsed 1.00134375s

func Parallelize2

func Parallelize2[K, V any](
	seq iter.Seq2[K, V],
	f Parallelize2Func[K, V],
	opts ...ParallelizeOptionFunc,
)

Parallelize2 runs a function on each value in an iter.Seq2 sequence on separate goroutines.

Example
package main

import (
	"fmt"
	"time"

	"github.com/alvii147/gloop"
)

func main() {
	printlnWithDelay := func(k string, v int) {
		time.Sleep(time.Second)
		fmt.Println(k, v)
	}

	m := map[string]int{
		"CAT":   3,
		"DOG":   1,
		"MOUSE": 4,
	}
	timeElaped := time.Now()

	gloop.Parallelize2(gloop.Map(m), printlnWithDelay)
	fmt.Println("Time Elapsed", time.Since(timeElaped))
}
Output:

MOUSE 4
CAT 3
DOG 1
Time Elapsed 1.00058975s

func Permutations

func Permutations[V any](seq iter.Seq[V], size int) iter.Seq[iter.Seq[V]]

Permutations allows looping over all permutations of a given size for an iter.Seq sequence. The size must be positive.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	s := "CAT"
	for seq := range gloop.Permutations(gloop.String(s), 2) {
		perm := gloop.ToString(seq)
		fmt.Println(perm)
	}
}
Output:

CA
CT
AC
AT
TC
TA

func Permutations2

func Permutations2[K, V any](seq iter.Seq2[K, V], size int) iter.Seq[iter.Seq2[K, V]]

Permutations2 allows looping over all permutations of a given size for an iter.Seq2 sequence. The size must be positive.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	m := map[string]int{
		"CAT":   3,
		"DOG":   1,
		"MOUSE": 4,
	}
	for seq := range gloop.Permutations2(gloop.Map(m), 2) {
		permKeys, permValues := gloop.ToSlice2(seq)
		fmt.Println(permKeys, permValues)
	}
}
Output:

[CAT DOG] [3 1]
[CAT MOUSE] [3 4]
[DOG CAT] [1 3]
[DOG MOUSE] [1 4]
[MOUSE CAT] [4 3]
[MOUSE DOG] [4 1]

func Product

func Product[V Productable](seq iter.Seq[V]) V

Product computes the product of values over an iter.Seq sequence.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4}
	prod := gloop.Product(gloop.Slice(values))
	fmt.Println(prod)
}
Output:

12

func RandomNormal

func RandomNormal[N Number](
	mean N,
	stddev N,
	size int,
	opts ...RandomOptionFunc,
) iter.Seq[float64]

RandomNormal allows looping over a given number of random values drawn from a Gaussian distribution. The size must not be negative and the standard deviation must be positive.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	for i := range gloop.RandomNormal(2, 2, 5) {
		fmt.Println(i)
	}
}
Output:

3.6053409359773543
4.8493077906535165
1.321369004660313
1.3549030774712296
-0.6521572615302738

func RandomUniform

func RandomUniform[N Number](
	low N,
	high N,
	size int,
	opts ...RandomOptionFunc,
) iter.Seq[float64]

RandomUniform allows looping over a given number of random values drawn from a uniform distribution. The size must not be negative.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	for i := range gloop.RandomUniform(0, 2, 5) {
		fmt.Println(i)
	}
}
Output:

1.7336396942444041
0.9684446802268123
1.5762348358917075
0.5000463191262544
1.1113562403363295

func Reduce

func Reduce[V any](seq iter.Seq[V], f ReduceFunc[V]) V

Reduce runs a given function on each adjacent pair in an iter.Seq sequence and accumulates the result into a single value.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4}
	minValue := gloop.Reduce(gloop.Slice(values), func(value1 int, value2 int) int {
		return min(value1, value2)
	})
	fmt.Println(minValue)
}
Output:

1

func Reduce2

func Reduce2[K, V any](seq iter.Seq2[K, V], f Reduce2Func[K, V]) (K, V)

Reduce2 runs a given function on each adjacent pair of keys and values in an iter.Seq2 sequence and accumulates the result into a single key and value pair.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	minKeyValueFunc := func(k1 int, v1 int, k2 int, v2 int) (int, int) {
		if v1 < v2 {
			return k1, v1
		}

		return k2, v2
	}

	m := map[int]int{
		0: 3,
		1: 1,
		2: 4,
	}

	minValueKey, minValue := gloop.Reduce2(gloop.Map(m), minKeyValueFunc)
	fmt.Println(minValueKey, minValue)
}
Output:

1 1

func Reverse

func Reverse[V any](seq iter.Seq[V]) iter.Seq[V]

Reverse allows looping over an iter.Seq sequence in order of descending index.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4}
	for i := range gloop.Reverse(gloop.Slice(values)) {
		fmt.Println(i)
	}
}
Output:

4
1
3

func Reverse2

func Reverse2[K, V any](seq iter.Seq2[K, V]) iter.Seq2[K, V]

Reverse2 allows looping over an iter.Seq2 sequence in order of descending index.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4}
	for i, value := range gloop.Reverse2(gloop.Enumerate(gloop.Slice(values))) {
		fmt.Println(i, value)
	}
}
Output:

2 4
1 1
0 3

func Slice

func Slice[V any](values []V) iter.Seq[V]

Slice allows looping over a given slice.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4}
	for i := range gloop.Slice(values) {
		fmt.Println(i)
	}
}
Output:

3
1
4

func Sort

func Sort[V cmp.Ordered](seq iter.Seq[V], ascending bool) iter.Seq[V]

Sort allows looping over an iter.Seq sequence in sorted order.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4, 1, 5, 9}
	for i := range gloop.Sort(gloop.Slice(values), true) {
		fmt.Println(i)
	}
}
Output:

1
1
3
4
5
9

func SortByComparison

func SortByComparison[V any](
	seq iter.Seq[V],
	less SortByComparisonFunc[V],
	ascending bool,
) iter.Seq[V]

SortByComparison allows looping over an iter.Seq sequence in sorted order using a comparison function.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	compareStringLens := func(s1, s2 string) bool {
		return len(s1) < len(s2)
	}

	values := []string{"CAT", "MOUSE", "DOG"}
	for s := range gloop.SortByComparison(gloop.Slice(values), compareStringLens, true) {
		fmt.Println(s)
	}
}
Output:

CAT
DOG
MOUSE

func SortByComparison2

func SortByComparison2[K, V any](
	seq iter.Seq2[K, V],
	less SortByComparison2Func[K, V],
	ascending bool,
) iter.Seq2[K, V]

SortByComparison2 allows looping over an iter.Seq2 sequence in sorted order using a comparison function.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	compareKeyValueConcatLen := func(k1, v1, k2, v2 string) bool {
		return len(k1+v1) < len(k2+v2)
	}

	values := map[string]string{
		"CAT":   "DOG",
		"MOUSE": "CHICKEN",
		"BUNNY": "BEAR",
	}
	for key, value := range gloop.SortByComparison2(gloop.Map(values), compareKeyValueConcatLen, true) {
		fmt.Println(key, value)
	}
}
Output:

CAT DOG
BUNNY BEAR
MOUSE CHICKEN

func SortByRank

func SortByRank[V any, R cmp.Ordered](
	seq iter.Seq[V],
	rank SortByRankFunc[V, R],
	ascending bool,
) iter.Seq[V]

SortByRank allows looping over an iter.Seq sequence in sorted order using a ranking function.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	stringLen := func(s string) int {
		return len(s)
	}

	values := []string{"CAT", "MOUSE", "DOG"}
	for s := range gloop.SortByRank(gloop.Slice(values), stringLen, true) {
		fmt.Println(s)
	}
}
Output:

CAT
DOG
MOUSE

func SortByRank2

func SortByRank2[K, V any, R cmp.Ordered](
	seq iter.Seq2[K, V],
	rank SortByRank2Func[K, V, R],
	ascending bool,
) iter.Seq2[K, V]

SortByRank2 allows looping over an iter.Seq2 sequence in sorted order using a ranking function.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	stringConcatLen := func(k1, v1 string) int {
		return len(k1 + v1)
	}

	values := map[string]string{
		"CAT":   "DOG",
		"MOUSE": "CHICKEN",
		"BUNNY": "BEAR",
	}
	for key, value := range gloop.SortByRank2(gloop.Map(values), stringConcatLen, true) {
		fmt.Println(key, value)
	}
}
Output:

CAT DOG
BUNNY BEAR
MOUSE CHICKEN

func String

func String(s string) iter.Seq[rune]

String allows looping over the runes in a given string.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	for r := range gloop.String("CAT") {
		fmt.Println(string(r))
	}
}
Output:

C
A
T

func Sum

func Sum[V Summable](seq iter.Seq[V]) V

Sum computes summation over an iter.Seq sequence.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4}
	sum := gloop.Sum(gloop.Slice(values))
	fmt.Println(sum)
}
Output:

8

func ToList

func ToList[V any](seq iter.Seq[V]) *list.List

ToList converts an iter.Seq sequence to a container/list.List.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq := func(yield func(int) bool) {
		yield(3)
		yield(1)
		yield(4)
	}

	l := gloop.ToList(seq)
	fmt.Println(l.Remove(l.Front()))
	fmt.Println(l.Remove(l.Front()))
	fmt.Println(l.Remove(l.Front()))
}
Output:

3
1
4

func ToList2

func ToList2[K, V any](seq iter.Seq2[K, V]) (*list.List, *list.List)

ToList2 converts an iter.Seq2 sequence to container/list.List of keys and values.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("MOUSE", 4)
	}

	keys, values := gloop.ToList2(seq)

	fmt.Println(keys.Remove(keys.Front()))
	fmt.Println(keys.Remove(keys.Front()))
	fmt.Println(keys.Remove(keys.Front()))
	fmt.Println(values.Remove(values.Front()))
	fmt.Println(values.Remove(values.Front()))
	fmt.Println(values.Remove(values.Front()))
}
Output:

CAT
DOG
MOUSE
3
1
4

func ToSlice

func ToSlice[V any](seq iter.Seq[V]) []V

ToSlice converts an iter.Seq sequence to a slice.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq := func(yield func(int) bool) {
		yield(3)
		yield(1)
		yield(4)
	}

	fmt.Println(gloop.ToSlice(seq))
}
Output:

[3 1 4]

func ToSlice2

func ToSlice2[K, V any](seq iter.Seq2[K, V]) ([]K, []V)

ToSlice2 converts an iter.Seq2 sequence to slices of keys and values.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("MOUSE", 4)
	}

	keys, values := gloop.ToSlice2(seq)
	fmt.Println(keys, values)
}
Output:

[CAT DOG MOUSE] [3 1 4]

func ToString

func ToString(seq iter.Seq[rune]) string

ToString converts an iter.Seq sequence of runes to a string.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq := func(yield func(rune) bool) {
		yield('C')
		yield('A')
		yield('T')
	}

	fmt.Println(gloop.ToString(seq))
}
Output:

CAT

func Transform

func Transform[V, T any](seq iter.Seq[V], f TransformFunc[V, T]) iter.Seq[T]

Transform runs a given function on each value over an iter.Seq sequence and allows looping over the returned values.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/alvii147/gloop"
)

func main() {
	values := []string{"CaT", "dOg"}
	for s := range gloop.Transform(gloop.Slice(values), strings.ToUpper) {
		fmt.Println(s)
	}
}
Output:

CAT
DOG

func Transform2

func Transform2[K, V, T any](seq iter.Seq2[K, V], f Transform2Func[K, V, T]) iter.Seq[T]

Transform2 runs a given function on each key and value over an iter.Seq2 sequence and allows looping over the returned values.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	concat := func(s1, s2 string) string {
		return s1 + s2
	}

	m := map[string]string{
		"CAT":   "DOG",
		"MOUSE": "CHICKEN",
	}

	for s := range gloop.Transform2(gloop.Map(m), concat) {
		fmt.Println(s)
	}
}
Output:

CATDOG
MOUSECHICKEN

func Values

func Values[K, V any](seq iter.Seq2[K, V]) iter.Seq[V]

Values allows looping over an iter.Seq2 and converting it to an iter.Seq sequence by discarding the key.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	m := map[string]int{
		"CAT":   3,
		"DOG":   1,
		"MOUSE": 4,
	}

	for value := range gloop.Values(gloop.Map(m)) {
		fmt.Println(value)
	}
}
Output:

3
1
4

func Window

func Window[V any](seq iter.Seq[V], size int) iter.Seq[iter.Seq[V]]

Window allows looping over an iter.Seq sequence in sliding windows of a given size.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []int{3, 1, 4, 1, 5, 9}
	for seq := range gloop.Window(gloop.Slice(values), 3) {
		window := gloop.ToSlice(seq)
		fmt.Println(window)
	}
}
Output:

[3 1 4]
[1 4 1]
[4 1 5]
[1 5 9]

func Window2

func Window2[K, V any](seq iter.Seq2[K, V], size int) iter.Seq[iter.Seq2[K, V]]

Window2 allows looping over an iter.Seq2 sequence in sliding windows of a given size.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values := []string{"CAT", "DOG", "MOUSE", "CHICKEN", "BUNNY", "BEAR"}
	for seq := range gloop.Window2(gloop.Enumerate(gloop.Slice(values)), 3) {
		windowKeys, windowValues := gloop.ToSlice2(seq)
		fmt.Println(windowKeys, windowValues)
	}
}
Output:

[0 1 2] [CAT DOG MOUSE]
[1 2 3] [DOG MOUSE CHICKEN]
[2 3 4] [MOUSE CHICKEN BUNNY]
[3 4 5] [CHICKEN BUNNY BEAR]

func Zip

func Zip[V1, V2 any](
	seq1 iter.Seq[V1],
	seq2 iter.Seq[V2],
	opts ...ZipOptionFunc[V1, V2],
) iter.Seq2[V1, V2]

Zip allows looping over two iter.Seq sequences in pairs.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values1 := []string{"CAT", "DOG", "MOUSE"}
	values2 := []int{3, 1, 4}
	for value1, value2 := range gloop.Zip(gloop.Slice(values1), gloop.Slice(values2)) {
		fmt.Println(value1, value2)
	}
}
Output:

CAT 3
DOG 1
MOUSE 4

func Zip2

func Zip2[K1, V1, K2, V2 any](
	seq1 iter.Seq2[K1, V1],
	seq2 iter.Seq2[K2, V2],
	opts ...Zip2OptionFunc[K1, V1, K2, V2],
) iter.Seq2[KeyValuePair[K1, V1], KeyValuePair[K2, V2]]

Zip2 allows looping over two iter.Seq2 sequences in pairs.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq1 := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("MOUSE", 4)
	}

	seq2 := func(yield func(int, float64) bool) {
		yield(3, 1.2)
		yield(1, 3.4)
		yield(4, 5.6)
	}

	for pair1, pair2 := range gloop.Zip2(seq1, seq2) {
		fmt.Println(pair1.Key, pair1.Value, pair2.Key, pair2.Value)
	}
}
Output:

CAT 3 3 1.2
DOG 1 1 3.4
MOUSE 4 4 5.6

func ZipN

func ZipN[V any](
	seqs iter.Seq[iter.Seq[V]],
	opts ...ZipNOptionFunc[V],
) iter.Seq[iter.Seq[V]]

ZipN allows looping over multiple iter.Seq sequences simultaneously.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq1 := gloop.Slice([]string{"CAT", "DOG"})
	seq2 := gloop.Slice([]string{"MOUSE", "CHICKEN"})
	seq3 := gloop.Slice([]string{"BUNNY", "BEAR"})

	for seq := range gloop.ZipN(gloop.Collect(seq1, seq2, seq3)) {
		fmt.Println(gloop.ToSlice(seq))
	}
}
Output:

[CAT MOUSE BUNNY]
[DOG CHICKEN BEAR]

func ZipN2

func ZipN2[K, V any](
	seqs iter.Seq[iter.Seq2[K, V]],
	opts ...ZipN2OptionFunc[K, V],
) iter.Seq[iter.Seq2[K, V]]

ZipN2 allows looping over multiple iter.Seq2 sequences simultaneously.

Example
package main

import (
	"fmt"
	"iter"

	"github.com/alvii147/gloop"
)

func main() {
	var seq1 iter.Seq2[string, int] = func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("MOUSE", 4)
	}

	var seq2 iter.Seq2[string, int] = func(yield func(string, int) bool) {
		yield("MOUSE", 1)
		yield("BUNNY", 5)
		yield("BEAR", 9)
	}

	for seq := range gloop.ZipN2(gloop.Collect(seq1, seq2)) {
		keys, values := gloop.ToSlice2(seq)
		fmt.Println(keys, values)
	}
}
Output:

[CAT MOUSE] [3 1]
[DOG BUNNY] [1 5]
[MOUSE BEAR] [4 9]

Types

type ComplexNumber

type ComplexNumber interface {
	~complex64 | ~complex128
}

ComplexNumber represents all complex number types.

type DeferLoopFunc

type DeferLoopFunc func(func())

DeferLoopFunc is the function signature of the defer function used in DeferLoop.

type Filter2Func

type Filter2Func[K, V any] func(K, V) bool

Filter2Func is the function signature of the filtering function used in Filter2.

type FilterFunc

type FilterFunc[V any] func(V) bool

FilterFunc is the function signature of the filtering function used in Filter.

type FloatingPoint

type FloatingPoint interface {
	~float32 | ~float64
}

FloatingPoint represents all floating point number types.

type Fold2Func

type Fold2Func[A, K, V any] func(A, K, V) A

Fold2Func is the function signature of the reduction function used in Fold2.

type FoldFunc

type FoldFunc[A, V any] func(A, V) A

FoldFunc is the function signature of the folding function used in Fold.

type FoldOptionFunc

type FoldOptionFunc[A any] func(*FoldOptions[A])

FoldOptionFunc is the function signature of configuration helpers for Fold and Fold2.

func WithFoldInitialValue

func WithFoldInitialValue[A any](initialValue A) FoldOptionFunc[A]

WithFoldInitialValue is a helper for configuring initial value for Fold and Fold2.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	multiply := func(a, b int) int {
		return a * b
	}

	values := []int{3, 1, 4}
	prod := gloop.Fold(
		gloop.Slice(values),
		multiply,
		gloop.WithFoldInitialValue(1),
	)
	fmt.Println(prod)
}
Output:

12

type FoldOptions

type FoldOptions[A any] struct {
	// InitialValue is the starting value before folding.
	InitialValue *A
}

FoldOptions defines configurable options for Fold and Fold2.

type IntervalOptionFunc

type IntervalOptionFunc func(*IntervalOptions)

IntervalOptionFunc is the function signature of configuration helpers for Interval.

func WithIntervalClosed

func WithIntervalClosed(closed bool) IntervalOptionFunc

WithIntervalClosed is a helper for configuring the interval to be closed for Interval.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	for i := range gloop.Interval(3, 9, 2, gloop.WithIntervalClosed(true)) {
		fmt.Println(i)
	}
}
Output:

3
5
7
9

type IntervalOptions

type IntervalOptions struct {
	// Closed represents whether or not the interval is closed at the
	// stop point.
	Closed bool
}

IntervalOptions defines configurable options for Interval.

type KeyValuePair

type KeyValuePair[K, V any] struct {
	Key   K
	Value V
}

KeyValuePair represents a generic key value pair.

type LinspaceOptionFunc

type LinspaceOptionFunc func(*LinspaceOptions)

LinspaceOptionFunc is the function signature of configuration helpers for Linspace.

func WithLinspaceClosed

func WithLinspaceClosed(closed bool) LinspaceOptionFunc

WithLinspaceClosed is a helper for configuring the interval to be closed for Linspace.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	for i := range gloop.Linspace(2, 3, 5, gloop.WithLinspaceClosed(true)) {
		fmt.Println(i)
	}
}
Output:

2
2.25
2.5
2.75

type LinspaceOptions

type LinspaceOptions struct {
	// Closed represents whether or not the interval is closed at the
	// stop point.
	Closed bool
}

LinspaceOptions defines configurable options for Linspace.

type MaxByComparison2Func

type MaxByComparison2Func[K, V any] func(K, V, K, V) bool

MaxByComparison2Func is the function signature of the comparison function used in MaxByComparison2.

type MaxByComparisonFunc

type MaxByComparisonFunc[V any] func(V, V) bool

MaxByComparisonFunc is the function signature of the comparison function used in MaxByComparison].

type MaxByRank2Func

type MaxByRank2Func[K, V any, R cmp.Ordered] func(K, V) R

MaxByRank2Func is the function signature of the ranking function used in MaxByRank2.

type MaxByRankFunc

type MaxByRankFunc[V any, R cmp.Ordered] func(V) R

MaxByRankFunc is the function signature of the ranking function used in MaxByRank.

type MinByComparison2Func

type MinByComparison2Func[K, V any] func(K, V, K, V) bool

MinByComparison2Func is the function signature of the comparison function used in MinByComparison2.

type MinByComparisonFunc

type MinByComparisonFunc[V any] func(V, V) bool

MinByComparisonFunc is the function signature of the comparison function used in MinByComparison.

type MinByRank2Func

type MinByRank2Func[K, V any, R cmp.Ordered] func(K, V) R

MinByRank2Func is the function signature of the ranking function used in MinByRank2.

type MinByRankFunc

type MinByRankFunc[V any, R cmp.Ordered] func(V) R

MinByRankFunc is the function signature of the ranking function used in MinByRank.

type Number

type Number interface {
	SignedInteger |
		UnsignedInteger |
		FloatingPoint
}

Number represents all numeric types.

type Parallelize2Func

type Parallelize2Func[K, V any] func(K, V)

Parallelize2Func is the function signature of the function to be parallelized in Parallelize2.

type ParallelizeFunc

type ParallelizeFunc[V any] func(V)

ParallelizeFunc is the function signature of the function to be parallelized in Parallelize.

type ParallelizeOptionFunc

type ParallelizeOptionFunc func(*ParallelizeOptions)

ParallelizeOptionFunc is the function signature of configuration helpers for Parallelize and Parallelize2.

func WithParallelizeContext

func WithParallelizeContext(ctx context.Context) ParallelizeOptionFunc

WithParallelizeContext is a helper for configuring context in Parallelize and Parallelize2.

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/alvii147/gloop"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	cancel()

	printlnWithDelay := func(s string) {
		time.Sleep(time.Second)
		fmt.Println(s)
	}

	values := []string{"CAT", "DOG", "MOUSE"}
	timeElaped := time.Now()

	gloop.Parallelize(
		gloop.Slice(values),
		printlnWithDelay,
		gloop.WithParallelizeContext(ctx),
	)
	fmt.Println("Time Elapsed", time.Since(timeElaped))
}
Output:

Time Elapsed 72.25µs

func WithParallelizeMaxThreads

func WithParallelizeMaxThreads(maxThreads int) ParallelizeOptionFunc

WithParallelizeMaxThreads is a helper for configuring maximum number of concurrent threads in Parallelize and Parallelize2.

Example
package main

import (
	"fmt"
	"time"

	"github.com/alvii147/gloop"
)

func main() {
	printlnWithDelay := func(s string) {
		time.Sleep(time.Second)
		fmt.Println(s)
	}

	values := []string{"CAT", "DOG", "MOUSE"}
	timeElaped := time.Now()

	gloop.Parallelize(
		gloop.Slice(values),
		func(s string) {
			printlnWithDelay(s)
			fmt.Println(time.Since(timeElaped))
		},
		gloop.WithParallelizeMaxThreads(2),
	)
	fmt.Println("Time Elapsed", time.Since(timeElaped))
}
Output:

CAT
DOG
1.001328958s
1.001326916s
MOUSE
2.002552375s
Time Elapsed 2.002678125s

type ParallelizeOptions

type ParallelizeOptions struct {
	// Context is used to send a cancel signal.
	Context context.Context
	// MaxThreads defines the maximum number of concurrent threads
	// allowed. If nil, there is no maximum.
	MaxThreads *int
}

ParallelizeOptions defines configurable options for Parallelize and Parallelize2.

type Productable

type Productable interface {
	SignedInteger |
		UnsignedInteger |
		FloatingPoint |
		ComplexNumber
}

Productable represents all types that support multiplication through the "*" operator.

type RandomOptionFunc

type RandomOptionFunc func(*RandomOptions)

RandomOptionFunc is the function signature of configuration helpers for RandomUniform and RandomNormal.

func WithRandomGenerator

func WithRandomGenerator(generator *rand.Rand) RandomOptionFunc

WithRandomGenerator is a helper for configuring the random number generator for RandomUniform and RandomNormal.

Example
package main

import (
	"fmt"
	"math/rand"

	"github.com/alvii147/gloop"
)

func main() {
	rng := rand.New(rand.NewSource(42))
	for i := range gloop.RandomNormal(2, 2, 5, gloop.WithRandomGenerator(rng)) {
		fmt.Println(i)
	}
}
Output:

5.1072611169129525
2.250512173654094
1.0112503744590344
4.4880300301524105
2.263956968542141

type RandomOptions

type RandomOptions struct {
	// Generator is the random number generator.
	Generator *rand.Rand
}

RandomOptions defines configurable options for RandomUniform and RandomNormal.

type Reduce2Func

type Reduce2Func[K, V any] func(K, V, K, V) (K, V)

Reduce2Func is the function signature of the reducing function used in Reduce2.

type ReduceFunc

type ReduceFunc[V any] func(V, V) V

ReduceFunc is the function signature of the reducing function used in Reduce.

type SignedInteger

type SignedInteger interface {
	~int |
		~int8 |
		~int16 |
		~int32 |
		~int64
}

SignedInteger represents all signed integer types.

type SortByComparison2Func

type SortByComparison2Func[K, V any] func(K, V, K, V) bool

SortByComparison2Func is the function signature of the comparison function used in SortByComparison2.

type SortByComparisonFunc

type SortByComparisonFunc[V any] func(V, V) bool

SortByComparisonFunc is the function signature of the comparison function used in SortByComparison.

type SortByRank2Func

type SortByRank2Func[K, V any, R cmp.Ordered] func(K, V) R

SortByRank2Func is the function signature of the ranking function used in SortByRank2.

type SortByRankFunc

type SortByRankFunc[V any, R cmp.Ordered] func(V) R

SortByRankFunc is the function signature of the ranking function used in SortByRank.

type Summable

type Summable interface {
	SignedInteger |
		UnsignedInteger |
		FloatingPoint |
		ComplexNumber |
		~string
}

Summable represents all types that support summation through the "+" operator.

type Transform2Func

type Transform2Func[K, V, T any] func(K, V) T

TransformFunc is the function signature of the transformation function in Transform2.

type TransformFunc

type TransformFunc[V, T any] func(V) T

TransformFunc is the function signature of the transformation function in Transform.

type UnsignedInteger

type UnsignedInteger interface {
	~uint |
		~uint8 |
		~uint16 |
		~uint32 |
		~uint64 |
		~uintptr
}

UnsignedInteger represents all unsigned integer types.

type Zip2OptionFunc

type Zip2OptionFunc[K1, V1, K2, V2 any] func(*Zip2Options[K1, V1, K2, V2])

Zip2OptionFunc is the function signature of configuration helpers for Zip2.

func WithZip2PadKey1

func WithZip2PadKey1[K1, V1, K2, V2 any](key K1) Zip2OptionFunc[K1, V1, K2, V2]

WithZip2PadKey1 is a helper for configuring padded keys for the first sequence in Zip2.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq1 := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("MOUSE", 4)
	}

	seq2 := func(yield func(int, float64) bool) {
		yield(3, 1.2)
		yield(1, 3.4)
		yield(4, 5.6)
		yield(1, 7.8)
		yield(5, 9.1)
		yield(9, 2.3)
	}

	for pair1, pair2 := range gloop.Zip2(
		seq1,
		seq2,
		gloop.WithZip2Padded[string, int, int, float64](true),
		gloop.WithZip2PadKey1[string, int, int, float64]("CHICKEN"),
	) {
		fmt.Println(pair1.Key, pair1.Value, pair2.Key, pair2.Value)
	}
}
Output:

CAT 3 3 1.2
DOG 1 1 3.4
MOUSE 4 4 5.6
CHICKEN 0 1 7.8
CHICKEN 0 5 9.1
CHICKEN 0 9 2.3

func WithZip2PadKey2

func WithZip2PadKey2[K1, V1, K2, V2 any](key K2) Zip2OptionFunc[K1, V1, K2, V2]

WithZip2PadKey2 is a helper for configuring padded keys for the second sequence in Zip2.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq1 := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("MOUSE", 4)
		yield("CHICKEN", 1)
		yield("BUNNY", 5)
		yield("BEAR", 9)
	}

	seq2 := func(yield func(int, float64) bool) {
		yield(3, 1.2)
		yield(1, 3.4)
		yield(4, 5.6)
	}

	for pair1, pair2 := range gloop.Zip2(
		seq1,
		seq2,
		gloop.WithZip2Padded[string, int, int, float64](true),
		gloop.WithZip2PadKey2[string, int, int, float64](42),
	) {
		fmt.Println(pair1.Key, pair1.Value, pair2.Key, pair2.Value)
	}
}
Output:

CAT 3 3 1.2
DOG 1 1 3.4
MOUSE 4 4 5.6
CHICKEN 1 42 0
BUNNY 5 42 0
BEAR 9 42 0

func WithZip2PadValue1

func WithZip2PadValue1[K1, V1, K2, V2 any](value V1) Zip2OptionFunc[K1, V1, K2, V2]

WithZip2PadValue1 is a helper for configuring padded values for the first sequence in Zip2.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq1 := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("MOUSE", 4)
	}

	seq2 := func(yield func(int, float64) bool) {
		yield(3, 1.2)
		yield(1, 3.4)
		yield(4, 5.6)
		yield(1, 7.8)
		yield(5, 9.1)
		yield(9, 2.3)
	}

	for pair1, pair2 := range gloop.Zip2(
		seq1,
		seq2,
		gloop.WithZip2Padded[string, int, int, float64](true),
		gloop.WithZip2PadValue1[string, int, int, float64](42),
	) {
		fmt.Println(pair1.Key, pair1.Value, pair2.Key, pair2.Value)
	}
}
Output:

CAT 3 3 1.2
DOG 1 1 3.4
MOUSE 4 4 5.6
 42 1 7.8
 42 5 9.1
 42 9 2.3

func WithZip2PadValue2

func WithZip2PadValue2[K1, V1, K2, V2 any](value V2) Zip2OptionFunc[K1, V1, K2, V2]

WithZip2PadValue2 is a helper for configuring padded values for the second sequence in Zip2.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq1 := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("MOUSE", 4)
		yield("CHICKEN", 1)
		yield("BUNNY", 5)
		yield("BEAR", 9)
	}

	seq2 := func(yield func(int, float64) bool) {
		yield(3, 1.2)
		yield(1, 3.4)
		yield(4, 5.6)
	}

	for pair1, pair2 := range gloop.Zip2(
		seq1,
		seq2,
		gloop.WithZip2Padded[string, int, int, float64](true),
		gloop.WithZip2PadValue2[string, int, int](4.2),
	) {
		fmt.Println(pair1.Key, pair1.Value, pair2.Key, pair2.Value)
	}
}
Output:

CAT 3 3 1.2
DOG 1 1 3.4
MOUSE 4 4 5.6
CHICKEN 1 0 4.2
BUNNY 5 0 4.2
BEAR 9 0 4.2

func WithZip2Padded

func WithZip2Padded[K1, V1, K2, V2 any](padded bool) Zip2OptionFunc[K1, V1, K2, V2]

WithZip2Padded is a helper for configuring Zip2 to pad the shorter sequence.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq1 := func(yield func(string, int) bool) {
		yield("CAT", 3)
		yield("DOG", 1)
		yield("MOUSE", 4)
		yield("CHICKEN", 1)
		yield("BUNNY", 5)
		yield("BEAR", 9)
	}

	seq2 := func(yield func(int, float64) bool) {
		yield(3, 1.2)
		yield(1, 3.4)
		yield(4, 5.6)
	}

	for pair1, pair2 := range gloop.Zip2(
		seq1,
		seq2,
		gloop.WithZip2Padded[string, int, int, float64](true),
	) {
		fmt.Println(pair1.Key, pair1.Value, pair2.Key, pair2.Value)
	}
}
Output:

CAT 3 3 1.2
DOG 1 1 3.4
MOUSE 4 4 5.6
CHICKEN 1 0 0
BUNNY 5 0 0
BEAR 9 0 0

type Zip2Options

type Zip2Options[K1, V1, K2, V2 any] struct {
	// Padded indicates whether the shorter sequence will be padded. If
	// true, the shorter sequence is padded to match the length of the
	// longer one. If false, the number of iterations is equal to the
	// length of the shorter sequence.
	Padded bool
	// PadKey1 is the key the first sequence is padded with. This is
	// not used if Padded is false or if the first sequence is shorter
	// than the second.
	PadKey1 *K1
	// PadValue1 is the value the first sequence is padded with. This
	// is not used if Padded is false or if the first sequence is
	// shorter than the second.
	PadValue1 *V1
	// PadKey2 is the key the second sequence is padded with. This is
	// not used if Padded is false or if the first sequence is shorter
	// than the second.
	PadKey2 *K2
	// PadValue2 is the value the second sequence is padded with. This
	// is not used if Padded is false or if the second sequence is
	// shorter than the first.
	PadValue2 *V2
}

Zip2Options defines configurable options for Zip2.

type ZipN2OptionFunc

type ZipN2OptionFunc[K, V any] func(*ZipN2Options[K, V])

ZipN2OptionFunc is the function signature of configuration helpers for ZipN2.

func WithZipN2PadKey

func WithZipN2PadKey[K, V any](key K) ZipN2OptionFunc[K, V]

WithZipN2PadKey is a helper for configuring padded keys in ZipN2. first sequence in Zip2.

Example
package main

import (
	"fmt"
	"iter"

	"github.com/alvii147/gloop"
)

func main() {
	var seq1 iter.Seq2[int, float64] = func(yield func(int, float64) bool) {
		yield(3, 1.4)
		yield(1, 5.9)
		yield(2, 6.5)
	}

	var seq2 iter.Seq2[int, float64] = func(yield func(int, float64) bool) {
		yield(3, 5.8)
		yield(9, 7.9)
	}

	for seq := range gloop.ZipN2(
		gloop.Collect(seq1, seq2),
		gloop.WithZipN2Padded[int, float64](true),
		gloop.WithZipN2PadKey[int, float64](42),
	) {
		keys, values := gloop.ToSlice2(seq)
		fmt.Println(keys, values)
	}
}
Output:

[3 3] [1.4 5.8]
[1 9] [5.9 7.9]
[2 42] [6.5 0]

func WithZipN2PadValue

func WithZipN2PadValue[K, V any](value V) ZipN2OptionFunc[K, V]

WithZipN2PadValue is a helper for configuring padded values in ZipN2.

Example
package main

import (
	"fmt"
	"iter"

	"github.com/alvii147/gloop"
)

func main() {
	var seq1 iter.Seq2[int, float64] = func(yield func(int, float64) bool) {
		yield(3, 1.4)
		yield(1, 5.9)
		yield(2, 6.5)
	}

	var seq2 iter.Seq2[int, float64] = func(yield func(int, float64) bool) {
		yield(3, 5.8)
		yield(9, 7.9)
	}

	for seq := range gloop.ZipN2(
		gloop.Collect(seq1, seq2),
		gloop.WithZipN2Padded[int, float64](true),
		gloop.WithZipN2PadValue[int](4.2),
	) {
		keys, values := gloop.ToSlice2(seq)
		fmt.Println(keys, values)
	}
}
Output:

[3 3] [1.4 5.8]
[1 9] [5.9 7.9]
[2 0] [6.5 4.2]

func WithZipN2Padded

func WithZipN2Padded[K, V any](padded bool) ZipN2OptionFunc[K, V]

WithZipN2Padded is a helper for configuring ZipN2 to pad the shorter sequence.

Example
package main

import (
	"fmt"
	"iter"

	"github.com/alvii147/gloop"
)

func main() {
	var seq1 iter.Seq2[int, float64] = func(yield func(int, float64) bool) {
		yield(3, 1.4)
		yield(1, 5.9)
		yield(2, 6.5)
	}

	var seq2 iter.Seq2[int, float64] = func(yield func(int, float64) bool) {
		yield(3, 5.8)
		yield(9, 7.9)
	}

	for seq := range gloop.ZipN2(
		gloop.Collect(seq1, seq2),
		gloop.WithZipN2Padded[int, float64](true),
	) {
		keys, values := gloop.ToSlice2(seq)
		fmt.Println(keys, values)
	}
}
Output:

[3 3] [1.4 5.8]
[1 9] [5.9 7.9]
[2 0] [6.5 0]

type ZipN2Options

type ZipN2Options[K, V any] struct {
	// Padded indicates whether the shorter sequence will be padded. If
	// true, the shorter sequence is padded to match the length of the
	// longer one. If false, the number of iterations is equal to the
	// length of the shorter sequence.
	Padded bool
	// PadKey is the key the shorter sequence is padded with. This is
	// not used if Padded is false or if both sequences are equal in
	// length.
	PadKey *K
	// PadValue is the value the shorter sequence is padded with. This
	// is not used if Padded is false or if both sequences are equal
	// in length.
	PadValue *V
}

ZipN2Options defines configurable options for ZipN2.

type ZipNOptionFunc

type ZipNOptionFunc[V any] func(*ZipNOptions[V])

ZipNOptionFunc is the function signature of configuration helpers for ZipN.

func WithZipNPadValue

func WithZipNPadValue[V any](value V) ZipNOptionFunc[V]

WithZipNPadValue is a helper for configuring padded values in ZipN.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq1 := gloop.Slice([]int{3, 1, 4})
	seq2 := gloop.Slice([]int{1, 5, 9})
	seq3 := gloop.Slice([]int{2, 7})

	for seq := range gloop.ZipN(
		gloop.Collect(seq1, seq2, seq3),
		gloop.WithZipNPadded[int](true),
		gloop.WithZipNPadValue(42),
	) {
		fmt.Println(gloop.ToSlice(seq))
	}
}
Output:

[3 1 2]
[1 5 7]
[4 9 42]

func WithZipNPadded

func WithZipNPadded[V any](padded bool) ZipNOptionFunc[V]

WithZipNPadded is a helper for configuring ZipN to pad the shorter sequence.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	seq1 := gloop.Slice([]int{3, 1, 4})
	seq2 := gloop.Slice([]int{1, 5, 9})
	seq3 := gloop.Slice([]int{2, 7})

	for seq := range gloop.ZipN(
		gloop.Collect(seq1, seq2, seq3),
		gloop.WithZipNPadded[int](true),
	) {
		fmt.Println(gloop.ToSlice(seq))
	}
}
Output:

[3 1 2]
[1 5 7]
[4 9 0]

type ZipNOptions

type ZipNOptions[V any] struct {
	// Padded indicates whether the shorter sequence will be padded. If
	// true, the shorter sequence is padded to match the length of the
	// longer one. If false, the number of iterations is equal to the
	// length of the shorter sequence.
	Padded bool
	// PadValue is the value the shorter sequence is padded with. This
	// is not used if Padded is false or if both sequences are equal
	// in length.
	PadValue *V
}

ZipNOptions defines configurable options for ZipN.

type ZipOptionFunc

type ZipOptionFunc[V1, V2 any] func(*ZipOptions[V1, V2])

ZipOptionFunc is the function signature of configuration helpers for Zip.

func WithZipPadValue1

func WithZipPadValue1[V1, V2 any](value V1) ZipOptionFunc[V1, V2]

WithZipPadValue1 is a helper for configuring padded values for the first sequence in Zip.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values1 := []string{"CAT", "DOG", "MOUSE"}
	values2 := []int{3, 1, 4, 1, 5, 9}
	for value1, value2 := range gloop.Zip(
		gloop.Slice(values1),
		gloop.Slice(values2),
		gloop.WithZipPadded[string, int](true),
		gloop.WithZipPadValue1[string, int]("BEAR"),
	) {
		fmt.Println(value1, value2)
	}
}
Output:

CAT 3
DOG 1
MOUSE 4
BEAR 1
BEAR 5
BEAR 9

func WithZipPadValue2

func WithZipPadValue2[V1, V2 any](value V2) ZipOptionFunc[V1, V2]

WithZipPadValue2 is a helper for configuring padded values for the second slice in Zip.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values1 := []string{"CAT", "DOG", "MOUSE", "CHICKEN", "BUNNY", "BEAR"}
	values2 := []int{3, 1, 4}
	for value1, value2 := range gloop.Zip(
		gloop.Slice(values1),
		gloop.Slice(values2),
		gloop.WithZipPadded[string, int](true),
		gloop.WithZipPadValue2[string](42),
	) {
		fmt.Println(value1, value2)
	}
}
Output:

CAT 3
DOG 1
MOUSE 4
CHICKEN 42
BUNNY 42
BEAR 42

func WithZipPadded

func WithZipPadded[V1, V2 any](padded bool) ZipOptionFunc[V1, V2]

WithZipPadded is a helper for configuring Zip to pad the shorter sequence.

Example
package main

import (
	"fmt"

	"github.com/alvii147/gloop"
)

func main() {
	values1 := []string{"CAT", "DOG", "MOUSE", "CHICKEN"}
	values2 := []int{3, 1, 4}
	for value1, value2 := range gloop.Zip(
		gloop.Slice(values1),
		gloop.Slice(values2),
		gloop.WithZipPadded[string, int](true),
	) {
		fmt.Println(value1, value2)
	}
}
Output:

CAT 3
DOG 1
MOUSE 4
CHICKEN 0

type ZipOptions

type ZipOptions[V1, V2 any] struct {
	// Padded indicates whether the shorter sequence will be padded. If
	// true, the shorter sequence is padded to match the length of the
	// longer one. If false, the number of iterations is equal to the
	// length of the shorter sequence.
	Padded bool
	// PadValue1 is the value the first sequence is padded with. This
	// is not used if Padded is false or if the first sequence is
	// shorter than the second.
	PadValue1 *V1
	// PadValue2 is the value the second sequence is padded with. This
	// is not used if Padded is false or if the second sequence is
	// shorter than the first.
	PadValue2 *V2
}

ZipOptions defines configurable options for Zip.

Jump to

Keyboard shortcuts

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