itermore

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2024 License: Apache-2.0 Imports: 5 Imported by: 0

README

itermore

Go Reference

range iterables with more features

Description

This package provides a set of functions to work with iterables in Go. It is partially inspired by Python's itertools module.

Available utils include for now:

  • iterator combinators: Chain, Zip, Skip, Take, etc.
  • iterator destructors: Collect, CollectJoin, CollectMap, etc.
  • iterator constructors: Items, For, ChanCtx, etc.

To use this package you need go 1.22 or later and you need to enable the rangefunc experiment until it is enabled by default.

export GOEXPERIMENT=rangefunc

Examples

func ExampleCollectJoin() {
	iter := itermore.Items("a", "b", "c")

	str := &strings.Builder{}

	itermore.CollectJoin(str, iter, ", ")

	fmt.Println(str.String())

	// Output: a, b, c
}
func ExampleChain() {
	one := itermore.One(1)
	xx := itermore.Items(10, 20, 30)

	for x := range itermore.Chain(one, xx) {
		fmt.Println(x)
	}

	// Output: 1
	// 10
	// 20
	// 30
}
func ExampleZip() {
	xx := itermore.Items(10, 20, 30)
	yy := itermore.Items("a", "b", "c")

	for x, y := range itermore.Zip(xx, yy) {
		fmt.Println(x, y)
	}
	// Output: 10 a
	// 20 b
	// 30 c
}

Roadmap

  • group by
  • iterable versions of standard library functions

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Chain

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

Chain creates a sequence that yields values from all provided sequences. Values are yielded in the order they appear in the arguments.

Example
package main

import (
	"fmt"

	"github.com/ninedraft/itermore"
)

func main() {
	one := itermore.One(1)
	xx := itermore.Items(10, 20, 30)

	for x := range itermore.Chain(one, xx) {
		fmt.Println(x)
	}

}
Output:

1
10
20
30

func Chan

func Chan[E any](ch <-chan E) iter.Seq[E]

Chan returns a new sequence that iterates over values from the given channel. If channel is nil, Chan returns an empty sequence. Closing channel will stop iteration.

func ChanCtx

func ChanCtx[E any](ctx context.Context, ch <-chan E) iter.Seq[E]

ChanCtx returns a new sequence that iterates over values from the given channel. If channel is nil, Chan returns an empty sequence. Closing channel will stop iteration. If ctx is canceled, ChanCtx will stop iteration.

Example
package main

import (
	"context"
	"fmt"

	"github.com/ninedraft/itermore"
)

func main() {
	ch := make(chan int, 3)
	ch <- 10
	ch <- 20
	ch <- 30
	close(ch)

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// easy cancelation of range-over-chan loop
	iter := itermore.ChanCtx(ctx, ch)

	for x := range iter {
		fmt.Println(x)
	}

}
Output:

10
20
30

func Collect

func Collect[S ~[]E, E any](dst S, seq iter.Seq[E]) S

Collect writes values from provided sequence to the given slice. If dst slice is nil, Collect will create a new slice. It can return a new slice or the same slice that was passed as dst following the same rules as append function.

func CollectChan

func CollectChan[E any](ch chan<- E, seq iter.Seq[E])

func CollectChanCtx

func CollectChanCtx[E any](ctx context.Context, ch chan<- E, seq iter.Seq[E])

func CollectJoin

func CollectJoin[S ~string](wr io.StringWriter, seq iter.Seq[S], sep string) (int64, error)

CollectJoin writes values from provided sequence to the given writer.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/ninedraft/itermore"
)

func main() {
	iter := itermore.Items("a", "b", "c")

	str := &strings.Builder{}

	itermore.CollectJoin(str, iter, ", ")

	fmt.Println(str.String())

}
Output:

a, b, c

func CollectJoinBytes

func CollectJoinBytes[P ~[]byte](wr io.Writer, seq iter.Seq[P], sep []byte) (int64, error)

CollectJoinBytes writes values from provided sequence to the given writer.

func CollectKeys

func CollectKeys[S ~map[K]V, K comparable, V any](dst S, value V, seq iter.Seq[K])

CollectKeys writes keys from provided sequence to the given map and assigns them the given value. It can be used to create a set from a sequence. It will panic if dst is nil.

func CollectMap

func CollectMap[M ~map[K]V, K comparable, V any](dst M, seq iter.Seq2[K, V])

CollectMap writes key-value pairs from provided sequence to the given map. It will panic if dst is nil.

func Compact

func Compact[E comparable](seq iter.Seq[E]) iter.Seq[E]

Compact returns a sequence, which yields values from seq, but skips consecutive duplicates. It roughly equal to slices.Compact.

func Enumerate

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

Enumerate creates a sequence that yields values from the given sequence with their indexes. If number of values in the sequence is greater then math.MaxInt, counter will wrap around.

func FlattenSlices added in v0.2.0

func FlattenSlices[E any](seq iter.Seq[[]E]) iter.Seq[E]

FlattenSlices walks through provided sequence and emits each element from sequenced slice.

Example:

[1, 2, 3] [4, 5, 6] -> 1, 2, 3, 4, 5, 6
Example
package main

import (
	"fmt"

	"github.com/ninedraft/itermore"
)

func main() {
	rows := itermore.Slice([][]int{
		{1, 2},
		{3, 4},
	})

	items := itermore.FlattenSlices(rows)

	for x := range items {
		fmt.Printf("%d ", x)
	}

}
Output:

1 2 3 4

func For

func For[N Number](start, to, step N) iter.Seq[N]

For behaves like a for loop with a counter. It can be though as following code:

start <= to: for i := start; i < to; i += step
start > to:  for i := start; i > to; i += step

func Forever

func Forever[E any](value E) iter.Seq[E]

Forever creates an infinite sequence that yields a single value.

func ForeverFn

func ForeverFn[E any](fn func() E) iter.Seq[E]

ForeverFn creates an infinite sequence that yields a single value from the given function.

func Items

func Items[E any](items ...E) iter.Seq[E]

Items creates a sequence that yields values from the given variadic arguments. If no arguments are provided, the sequence will be empty. It's a shortcut for Slice([]E{items...}).

func Loop

func Loop[E any](items []E) iter.Seq[E]

Loop forever yields values from the given slice in the order they appear in the slice. After the last value is yielded, the sequence will start from the beginning.

func Map

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

Map creates a sequence that yields key-value pairs from the given map. If map nil or empty, the sequence will be empty.

func Max

func Max[E cmp.Ordered](seq iter.Seq[E]) (E, bool)

Max returns the largest element in the sequence. If sequence is empty, Max returns false. If there is a single item in the sequence, Max returns it. It roughly equal to slices.Max.

func Min

func Min[E cmp.Ordered](seq iter.Seq[E]) (E, bool)

Min returns the smallest element in the sequence. If sequence is empty, Min returns false. If there is a single item in the sequence, Min returns it. It roughly equal to slices.Min.

func Next

func Next[E any](next func() (E, bool)) iter.Seq[E]

Next creates sequence that yields values from the given function.

func None

func None[E any](yield func(E) bool)

None creates an emptye sequence.

func None2

func None2[A, B any](yield func(A, B) bool)

None2 creates an emptye sequence of pairs.

func One

func One[E any](value E) iter.Seq[E]

One creates a sequence that yields a single value.

func One2

func One2[A, B any](a A, b B) iter.Seq2[A, B]

One2 creates a sequence that yields a single pair.

func SkipN

func SkipN[E any](n int, seq iter.Seq[E]) iter.Seq[E]

SkipN skips first n values from the given sequence. If n is greater then number of values in the sequence, SkipN will return an empty sequence. If n is negative or zero, SkipN will return an empty sequence.

func Slice

func Slice[E any](items []E) iter.Seq[E]

Slice creates a sequence that yields values from the given slice. If slice is nil or empty, the sequence will be empty.

func TakeN

func TakeN[E any](n int, seq iter.Seq[E]) iter.Seq[E]

TakeN yields first n values from the given sequence. If n is greater then number of values in the sequence, TakeN will yield all values from the sequence. If n is negative or zero, TakeN will return an empty sequence.

func Then

func Then[E any](seq iter.Seq[E], then func()) iter.Seq[E]

Then returns a sequence, which yields values from seq, then always calls then function. It calls then function even if seq is empty.

func YieldFrom

func YieldFrom[E any](yield func(E) bool, seq iter.Seq[E]) bool

YieldFrom pulls all values from the given sequence and yields them.

func YieldFrom2

func YieldFrom2[A, B any](yield func(A, B) bool, seq iter.Seq2[A, B]) bool

YieldFrom2 pulls all pairs from the given sequence and yields them.

func Zip

func Zip[A, B any](a iter.Seq[A], b iter.Seq[B]) iter.Seq2[A, B]

Zip creates a sequence that yields pairs of values from the given sequences. If any of the sequences is stopped, the sequence will stop.

Example
package main

import (
	"fmt"

	"github.com/ninedraft/itermore"
)

func main() {
	xx := itermore.Items(10, 20, 30)
	yy := itermore.Items("a", "b", "c")

	for x, y := range itermore.Zip(xx, yy) {
		fmt.Println(x, y)
	}
}
Output:

10 a
20 b
30 c

func ZipLongest

func ZipLongest[A, B any](a iter.Seq[A], b iter.Seq[B]) iter.Seq2[A, B]

ZipLongest creates a sequence that yields pairs of values from the given sequences. If any of the sequences is stopped, the sequence will continue to emit zero values for that sequence. If both sequences are stopped, the sequence will stop.

Types

type Number

type Number interface {
	constraints.Integer | constraints.Float
}

Number is a type, which can be added and compared.

Jump to

Keyboard shortcuts

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