hiter

package
v0.0.18 Latest Latest
Warning

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

Go to latest
Published: Dec 19, 2024 License: MIT Imports: 9 Imported by: 9

Documentation

Overview

hiter defines iterator sources from various inputs, adapters, collectors.

Example (Partition)

Example_partition demonstrates how you replace https://pkg.go.dev/github.com/samber/lo#PartitionBy with hiter.

package main

import (
	"fmt"
	"slices"

	"github.com/ngicks/go-iterator-helper/hiter"
)

func main() {
	mm := hiter.ReduceGroup(
		func(accumulator []int, current int) []int { return append(accumulator, current) },
		[]int(nil),
		hiter.WithGroupId(
			func(i int) string {
				if i < 0 {
					return "negative"
				} else if i%2 == 0 {
					return "even"
				}
				return "odd"
			},
			slices.Values([]int{-2, -1, 0, 1, 2, 3, 4, 5}),
		),
	)

	fmt.Printf(
		"%#v\n",
		slices.Collect(
			hiter.OmitF(
				hiter.MapKeys(
					mm,
					hiter.Range(0, len(mm)),
				),
			),
		),
	)
}
Output:

[][]int{[]int{-2, -1}, []int{0, 2, 4}, []int{1, 3, 5}}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Alternate

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

Alternate returns an iterator that yields alternatively each seq. The first exhausted seq stops the iterator.

Example
package main

import (
	"fmt"

	"github.com/ngicks/go-iterator-helper/hiter"
)

func main() {
	tick := hiter.Repeat("tick", 3)
	tac := hiter.Repeat("tac", 3)

	for msg := range hiter.Alternate(tick, tac) {
		fmt.Printf("%s ", msg)
	}
	fmt.Printf("ooooohhhhh...\n")
}
Output:

tick tac tick tac tick tac ooooohhhhh...

func Alternate2

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

Alternate returns an iterator that yields alternatively each seq. The first exhausted seq stops the iterator.

func Any added in v0.0.14

func Any[V any](fn func(V) bool, seq iter.Seq[V]) bool

Any returns true if any of values from seq satisfies fn. Otherwise it returns false.

func Any2 added in v0.0.14

func Any2[K, V any](fn func(K, V) bool, seq iter.Seq2[K, V]) bool

Any2 returns true if any of key-value pairs from seq satisfies fn. Otherwise it returns false.

func AppendBytes added in v0.0.13

func AppendBytes(b []byte, seq iter.Seq[[]byte]) []byte

AppendBytes appends byte slices from seq to b, and returns the extended slice.

func AppendSeq2

func AppendSeq2[S ~[]KeyValue[K, V], K, V any](s S, seq iter.Seq2[K, V]) S

AppendSeq2 appends the values from seq to the KeyValue slice and returns the extended slice.

func Assert added in v0.0.14

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

Assert returns an iterator over seq but each value is type-asserted to be type V.

func Assert2 added in v0.0.14

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

Assert2 returns an iterator over seq but each key-value pair is type-asserted to be type K and V respectively.

func AtterAll added in v0.0.16

func AtterAll[A interface {
	Atter[T]
	Lenner
}, T any](a A) iter.Seq2[int, T]

AtterAll is like AtterRange but start is 0 and end is result of [Lenner.Len].

func AtterIndices added in v0.0.16

func AtterIndices[A Atter[T], T any](a A, indices iter.Seq[int]) iter.Seq2[int, T]

AtterIndices returns an iterator over pairs of indices and values retrieved from an Atter using the indices. The indices sequence determines the order of access and must provide valid indices within the bounds of the Atter. If an out-of-range index is supplied, the behavior is undefined and may vary based on the Atter implementation.

Example
package main

import (
	"fmt"

	"github.com/ngicks/go-iterator-helper/hiter"
)

type atSliceStr []string

func (a atSliceStr) At(i int) string {
	return a[i]
}

func (a atSliceStr) Len() int {
	return len(a)
}

var atSliceSrc = atSliceStr{
	"foo", "bar", "baz",
	"qux", "quux", "corge",
	"grault", "garply", "waldo",
	"fred", "plugh", "xyzzy",
	"thud",
}

func main() {
	for i, s := range hiter.AtterIndices(atSliceSrc, hiter.Range(3, 7)) {
		fmt.Printf("%d: %s\n", i, s)
	}
}
Output:

3: qux
4: quux
5: corge
6: grault

func AtterRange added in v0.0.16

func AtterRange[A Atter[T], T any](a A, start, end int) iter.Seq2[int, T]

AtterRange is like AtterIndices but indices is result of calling Range with start and end.

func Chan

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

Chan returns an iterator over ch. Either cancelling ctx or closing ch stops iteration.

func ChanSend added in v0.0.8

func ChanSend[V any](ctx context.Context, c chan<- V, seq iter.Seq[V]) (v V, sentAll bool)

ChanSend sends values from seq to c. It unblocks after either ctx is cancelled or all values from seq are consumed. sentAll is true only when all values are sent to c. Otherwise sentAll is false and v is the value that is being blocked on sending to the channel.

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

var (
	in, out = make(chan string), make(chan string)
	wg      sync.WaitGroup
)

wg.Add(1)
go func() {
	defer wg.Done()
	hiter.ChanSend(ctx, in, hiter.Repeat("hey", 3))
}()

for range 3 {
	wg.Add(1)
	go func() {
		defer wg.Done()
		// super duper heavy tasks
		_, _ = hiter.ChanSend(
			ctx,
			out,
			hiter.Tap(
				func(_ string) {
					// sleep for random duration.
					// Ensuring moderate task distribution among workers(goroutines.)
					time.Sleep(rand.N[time.Duration](100))
				},
				xiter.Map(
					func(s string) string { return "✨" + s + "✨" },
					hiter.Chan(ctx, in),
				),
			),
		)
	}()
}

for i, decorated := range hiter.Enumerate(hiter.Chan(ctx, out)) {
	fmt.Printf("%s\n", decorated)
	if i == 2 {
		cancel()
	}
}
wg.Wait()
Output:

✨hey✨
✨hey✨
✨hey✨

func CheckEach added in v0.0.14

func CheckEach[V any](n int, check func(v V, i int) bool, seq iter.Seq[V]) iter.Seq[V]

CheckEach returns an iterator over seq. It also calls check after each n values yielded from seq. fn receives a value from seq and the current count of it to inspect and decide to stop. n is capped to 1 if it is less.

func CheckEach2 added in v0.0.14

func CheckEach2[K, V any](n int, check func(k K, v V, i int) bool, seq iter.Seq2[K, V]) iter.Seq2[K, V]

CheckEach2 returns an iterator over seq. It also calls check after each n key-value pairs yielded from seq. fn receives a key-value pair from seq and the current count of it to inspect and decide to stop. n is capped to 1 if it is less.

func Compact added in v0.0.11

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

Compact skips consecutive runs of equal elements from seq. The returned iterator is pure and stateless as long as seq is so.

Example
package main

import (
	"fmt"

	"github.com/ngicks/go-iterator-helper/hiter"
	"github.com/ngicks/go-iterator-helper/x/exp/xiter"
)

func main() {
	m := xiter.Merge(
		xiter.Map(func(i int) int { return 2 * i }, hiter.Range(1, 11)),
		xiter.Map(func(i int) int { return 1 << i }, hiter.Range(1, 11)),
	)

	first := true
	for i := range hiter.Compact(m) {
		if !first {
			fmt.Printf(", ")
		}
		fmt.Printf("%d", i)
		first = false
	}
	fmt.Println()
}
Output:

2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 32, 64, 128, 256, 512, 1024

func Compact2 added in v0.0.11

func Compact2[K, V comparable](seq iter.Seq2[K, V]) iter.Seq2[K, V]

Compact2 skips consecutive runs of equal k-v pairs from seq. The returned iterator is pure and stateless as long as seq is so.

func CompactFunc added in v0.0.11

func CompactFunc[V any](eq func(i, j V) bool, seq iter.Seq[V]) iter.Seq[V]

CompactFunc is like Compact but uses an equality function to compare elements. For runs of elements that compare equal, CompactFunc keeps the first one.

func CompactFunc2 added in v0.0.11

func CompactFunc2[K, V any](eq func(k1 K, v1 V, k2 K, v2 V) bool, seq iter.Seq2[K, V]) iter.Seq2[K, V]

CompactFunc2 is like Compact2 but uses an equality function to compare elements. For runs of elements that compare equal, CompactFunc2 keeps the first one.

Example
package main

import (
	"fmt"
	"slices"

	"github.com/ngicks/go-iterator-helper/hiter"
)

func main() {
	type example struct {
		Key  string
		Data string
	}
	for i, v := range hiter.CompactFunc2(
		func(i1 int, v1 example, i2 int, v2 example) bool { return v1.Key == v2.Key },
		hiter.Enumerate(slices.Values([]example{
			{"foo", "yay"}, {"foo", "nay"}, {"foo", "mah"},
			{"bar", "yay"},
			{"baz", "yay"}, {"baz", "nay"},
		})),
	) {
		fmt.Printf("%d: %v\n", i, v)
	}
}
Output:

0: {foo yay}
3: {bar yay}
4: {baz yay}

func Contains added in v0.0.18

func Contains[V comparable](v V, seq iter.Seq[V]) bool

Contains reports whether v is present in seq.

func Contains2 added in v0.0.18

func Contains2[K, V comparable](k K, v V, seq iter.Seq2[K, V]) bool

Contains2 reports whether k-v pair is present in seq.

func ContainsFunc added in v0.0.18

func ContainsFunc[V any](f func(V) bool, seq iter.Seq[V]) bool

ContainsFunc reports whether at least one element v of s satisfies f(v).

func ContainsFunc2 added in v0.0.18

func ContainsFunc2[K, V any](f func(K, V) bool, seq iter.Seq2[K, V]) bool

ContainsFunc2 reports whether at least one k-v pair of s satisfies f(k, v).

func Cycle added in v0.0.16

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

Cycle converts seq into an infinite iterator by repeatedly calling seq. seq is assumed to be finite but pure and reusable. The iterator may yield forever if seq is repeatable; stopping it is caller's responsibility.

func Cycle2 added in v0.0.16

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

Cycle2 converts seq into an infinite iterator by repeatedly calling seq. seq is assumed to be finite but pure and reusable. The iterator may yield forever if seq is repeatable; stopping it is caller's responsibility.

func CycleBuffered added in v0.0.16

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

CycleBuffered is like Cycle but seq is called only once. Values from seq is buffered and from second time and on, the iterator uses buffered contents.

seq must be finite and small, otherwise huge amount of memory will be consumed.

func CycleBuffered2 added in v0.0.16

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

CycleBuffered2 is like Cycle2 but seq is called only once. Key-Value pairs from seq is buffered and from second time and on, the iterator uses buffered contents.

seq must be finite and small, otherwise huge amount of memory will be consumed.

func Decorate

func Decorate[V any](prepend, append Iterable[V], seq iter.Seq[V]) iter.Seq[V]

Decorate decorates seq by prepend and append, by yielding additional elements before and after seq yields. Both prepend and append are allowed to be nil; only non-nil Iterable is used as decoration.

func Decorate2

func Decorate2[K, V any](prepend, append Iterable2[K, V], seq iter.Seq2[K, V]) iter.Seq2[K, V]

Decorate2 decorates seq by prepend and append, by yielding additional elements before and after seq yields. Both prepend and append are allowed to be nil; only non-nil Iterable2 is used as decoration.

func Discard added in v0.0.14

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

Discard fully consumes seq without doing anything.

func Discard2 added in v0.0.14

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

Discard2 fully consumes seq without doing anything.

func Divide added in v0.0.14

func Divide[K, V, U any](fn func(U) (K, V), seq iter.Seq[U]) iter.Seq2[K, V]

Divide splits values from seq to key-value pairs by applying fn to convert iter.Seq[U] to iter.Seq2[K, V].

func Empty added in v0.0.14

func Empty[V any]() iter.Seq[V]

Empty returns an iterator over nothing.

func Empty2 added in v0.0.14

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

Empty2 returns an iterator over nothing.

func Enumerate

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

Enumerate adds 0-indexed integer counts to every values from seq.

func Every added in v0.0.14

func Every[V any](fn func(V) bool, seq iter.Seq[V]) bool

Every checks every values from seq satisfying fn. Every return false immediately after it found the value dissatisfying fn, otherwise returns true.

func Every2 added in v0.0.14

func Every2[K, V any](fn func(K, V) bool, seq iter.Seq2[K, V]) bool

Every2 checks every key-value pairs from seq satisfying fn. Every2 return false immediately after it found the pair dissatisfying fn, otherwise returns true.

func Find added in v0.0.13

func Find[V comparable](v V, seq iter.Seq[V]) (V, int)

Find iterates over seq and the first value equals to v with its count. The count is 0-indexed and -1 if seq does not have value equals v.

func Find2 added in v0.0.13

func Find2[K, V comparable](k K, v V, seq iter.Seq2[K, V]) (K, V, int)

Find2 iterates over seq and the first k-v pair equals to k and v with its count. The count is 0-indexed and -1 if seq does not have k-v pairs equals the input.

func FindFunc added in v0.0.13

func FindFunc[V any](f func(V) bool, seq iter.Seq[V]) (V, int)

FindFunc iterates over seq and the first value satisfying fn(v) with its count. The count is 0-indexed and -1 if seq does not have value that satisfies fn.

func FindFunc2 added in v0.0.13

func FindFunc2[K, V any](fn func(K, V) bool, seq iter.Seq2[K, V]) (K, V, int)

FindFunc2 iterates over seq and the first k-v pair satisfying fn(v) with its count. The count is 0-indexed and -1 if seq does not have k-v pairs that satisfies fn.

func FindLast added in v0.0.13

func FindLast[V comparable](v V, seq iter.Seq[V]) (found V, idx int)

FindLast is like Find but returns the final occurrence of v. Unlike Find, FindLast always fully consumes seq.

func FindLast2 added in v0.0.13

func FindLast2[K, V comparable](k K, v V, seq iter.Seq2[K, V]) (foundK K, foundV V, idx int)

FindLast2 is like Find2 but returns the final occurrence of k-v pair.

func FindLastFunc added in v0.0.13

func FindLastFunc[V any](fn func(V) bool, seq iter.Seq[V]) (found V, idx int)

FindLastFunc is like FindFunc but returns the final occurrence of v.

func FindLastFunc2 added in v0.0.13

func FindLastFunc2[K, V any](fn func(K, V) bool, seq iter.Seq2[K, V]) (foundK K, foundV V, idx int)

FindLastFunc2 is like FindFunc2 but returns the final occurrence of k-v pair.

func First added in v0.0.13

func First[V any](seq iter.Seq[V]) (k V, ok bool)

First returns the first value from seq. ok is false if seq yields no value.

func First2 added in v0.0.13

func First2[K, V any](seq iter.Seq2[K, V]) (k K, v V, ok bool)

First2 returns the first key-value pair from seq. ok is false if seq yields no pair.

func Flatten

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

Flatten returns an iterator over each value of slices from seq.

Example
package main

import (
	"fmt"
	"slices"

	"github.com/ngicks/go-iterator-helper/hiter"
	"github.com/ngicks/go-iterator-helper/x/exp/xiter"
)

func main() {
	yayyay := []string{"yay", "yay", "yay"}
	wah := []string{"wah", "wah"}
	first := true
	for s := range hiter.Flatten(xiter.Concat(slices.Values([][]string{yayyay}), slices.Values([][]string{wah}))) {
		if !first {
			fmt.Print(" ")
		}
		fmt.Print(s)
		first = false
	}
}
Output:

yay yay yay wah wah

func FlattenF

func FlattenF[S1 ~[]E1, E1 any, E2 any](seq iter.Seq2[S1, E2]) iter.Seq2[E1, E2]

FlattenF returns an iterator over flattened key-value pairs from seq. While the iterator iterates over the former value from seq, the latter value is repeated.

Example
package main

import (
	"fmt"
	"slices"

	"github.com/ngicks/go-iterator-helper/hiter"
)

func main() {
	yayyay := []string{"yay", "yay", "yay"}
	ohYah := []string{"oh", "yah"}
	first := true
	for k, v := range hiter.FlattenF(hiter.Pairs(hiter.Repeat(yayyay, -1), slices.Values(ohYah))) {
		if !first {
			fmt.Print(" ")
		}
		fmt.Printf("{%s %s}", k, v)
		first = false
	}
}
Output:

{yay oh} {yay oh} {yay oh} {yay yah} {yay yah} {yay yah}

func FlattenL

func FlattenL[S2 ~[]E2, E1 any, E2 any](seq iter.Seq2[E1, S2]) iter.Seq2[E1, E2]

FlattenL returns an iterator over flattened key-value pairs from seq. While the iterator iterates over the latter value from seq, the former value is repeated.

Example
package main

import (
	"fmt"
	"slices"

	"github.com/ngicks/go-iterator-helper/hiter"
)

func main() {
	yayyay := []string{"yay", "yay", "yay"}
	ohYah := []string{"oh", "yah"}
	first := true
	for k, v := range hiter.FlattenL(hiter.Pairs(slices.Values(yayyay), hiter.Repeat(ohYah, -1))) {
		if !first {
			fmt.Print(" ")
		}
		fmt.Printf("{%s %s}", k, v)
		first = false
	}
}
Output:

{yay oh} {yay yah} {yay oh} {yay yah} {yay oh} {yay yah}

func FlattenSeq added in v0.0.14

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

Flatten returns and iterator over values from iterators from seq.

func FlattenSeq2 added in v0.0.14

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

FlattenSeq2 returns and iterator over key-value pairs from iterators from seq.

func FlattenSeqF added in v0.0.14

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

FlattenSeqF returns an iterator over flattened key-value pairs from seq. While the iterator iterates over the former value from seq, the latter value is repeated.

func FlattenSeqL added in v0.0.14

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

FlattenSeqF returns an iterator over flattened pairs from seq. While the iterator iterates over the latter value from seq, the former value is repeated.

func ForEach added in v0.0.14

func ForEach[V any](fn func(V), seq iter.Seq[V])

ForEach iterates over seq and calls fn with every value seq yields.

func ForEach2 added in v0.0.14

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

ForEach2 iterates over seq and calls fn with every key-value pair seq yields.

func ForEachGo added in v0.0.14

func ForEachGo[V any, G GoGroup](ctx context.Context, g G, fn func(context.Context, V) error, seq iter.Seq[V]) error

ForEachGo iterates over seq and calls fn with every value from seq in G's Go method. After all values are consumed, the result of Wait is returned. You may want to use *errgroup.Group as an implementor. see: https://pkg.go.dev/golang.org/x/sync/errgroup#Group

func ForEachGo2 added in v0.0.14

func ForEachGo2[K, V any, G GoGroup](ctx context.Context, g G, fn func(context.Context, K, V) error, seq iter.Seq2[K, V]) error

ForEachGo2 iterates over seq and calls fn with every key-value pair from seq in G's Go method. After all values are consumed, the result of Wait is returned. You may want to use *errgroup.Group as an implementor. see: https://pkg.go.dev/golang.org/x/sync/errgroup#Group

func FromKeyValue added in v0.0.13

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

FromKeyValue unwraps iter.Seq[KeyValue[K, V]] into iter.Seq2[K, V] serving as a counterpart for ToKeyValue.

In case values from seq needs to be sent through some data transfer mechanism that only allows data to be single value, like channels, some caller might decide to wrap values into KeyValue[K, V], maybe by ToKeyValue. If target helpers only accept iter.Seq2[K, V], then FromKeyValues is useful.

func InsertReduceGroup added in v0.0.14

func InsertReduceGroup[Map ~map[K]Sum, K comparable, V, Sum any](
	m Map,
	reducer func(accumulator Sum, current V) Sum,
	initial Sum,
	seq iter.Seq2[K, V],
) map[K]Sum

InsertReduceGroup is like ReduceGroup but inserts result to m.

func Last added in v0.0.13

func Last[V any](seq iter.Seq[V]) (v V, ok bool)

Last returns the last value from seq. ok is false if seq yields no value.

func Last2 added in v0.0.13

func Last2[K, V any](seq iter.Seq2[K, V]) (k K, v V, ok bool)

Last2 returns the last key-value pair from seq. ok is false if seq yields no pair.

func Limit added in v0.0.16

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

Limit returns an iterator over seq that stops after n values.

Note: Limit is redefined since xiter's implementation is stateful.

func Limit2 added in v0.0.16

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

Limit2 returns an iterator over seq that stops after n key-value pairs.

Note: Limit2 is redefined since xiter's implementation is stateful.

func LimitAfter added in v0.0.13

func LimitAfter[V any](f func(V) bool, seq iter.Seq[V]) iter.Seq[V]

LimitAfter is like LimitUntil but also yields the first value dissatisfying f(v).

func LimitAfter2 added in v0.0.13

func LimitAfter2[K, V any](f func(K, V) bool, seq iter.Seq2[K, V]) iter.Seq2[K, V]

LimitAfter2 is like LimitUntil2 but also yields the first pair dissatisfying f(k, v).

func LimitUntil

func LimitUntil[V any](f func(V) bool, seq iter.Seq[V]) iter.Seq[V]

LimitUntil returns an iterator over seq that yields until f returns false.

func LimitUntil2

func LimitUntil2[K, V any](f func(K, V) bool, seq iter.Seq2[K, V]) iter.Seq2[K, V]

LimitUntil2 returns an iterator over seq that yields until f returns false.

func MapKeys added in v0.0.16

func MapKeys[M ~map[K]V, K comparable, V any](m M, keys iter.Seq[K]) iter.Seq2[K, V]

MapKeys returns an iterator over pairs of keys and values retrieved from a map using the keys. The keys iterator determines the order of access.

func MapSorted added in v0.0.16

func MapSorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V]

MapSorted returns an iterator over key-value pairs from m. The iterator takes snapshot of keys from m at invocation and sorts keys in ascending order, which determines the order of paris.

Larger the map is, more the memory is consumed.

func MapSortedFunc added in v0.0.16

func MapSortedFunc[M ~map[K]V, K comparable, V any](m M, f func(i, j K) int) iter.Seq2[K, V]

MapSorted is like MapSorted but uses comparison function f to sort keys.

func Max added in v0.0.14

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

Max returns the maximum value of seq. Max returns the zero value if seq is empty.

func MaxFunc added in v0.0.14

func MaxFunc[V any](fn func(x, y V) int, seq iter.Seq[V]) V

MaxFunc returns the maximum value of seq using comparison function fn. fn must return -1 if x is less than y, 0 if x equals y, and +1 x is greater than y (as cmp.Compare does.) MaxFunc returns the zero value if seq is empty.

func MergeSort added in v0.0.11

func MergeSort[S ~[]T, T cmp.Ordered](m S) iter.Seq[T]

MergeSort implements merge sort algorithm. Basically you should use []T -> []T implementation since this allocates a lot more. MergeSort is worthy only when T is big structs and you only need one element at time, not a whole slice.

Example
package main

import (
	"cmp"
	"fmt"
	"iter"
	"slices"

	"github.com/ngicks/go-iterator-helper/hiter"
	"github.com/ngicks/go-iterator-helper/hiter/mathiter"
	"github.com/ngicks/go-iterator-helper/x/exp/xiter"
)

// avoiding xter dep
func limit[V any](seq iter.Seq[V], n int) iter.Seq[V] {
	return func(yield func(V) bool) {
		if n <= 0 {
			return
		}
		for v := range seq {
			if !yield(v) {
				return
			}
			if n--; n <= 0 {
				break
			}
		}
	}
}

func mergeSortFunc[S ~[]T, T any](m S, cmp func(l, r T) int) S {
	if len(m) <= 1 {
		return m
	}
	left, right := m[:len(m)/2], m[len(m)/2:]
	left = mergeSortFunc(left, cmp)
	right = mergeSortFunc(right, cmp)
	return mergeFunc(left, right, cmp)
}

func mergeFunc[S ~[]T, T any](l, r S, cmp func(l, r T) int) S {
	m := make(S, len(l)+len(r))
	var i int
	for i = 0; len(l) > 0 && len(r) > 0; i++ {
		if cmp(l[0], r[0]) < 0 {
			m[i] = l[0]
			l = l[1:]
		} else {
			m[i] = r[0]
			r = r[1:]
		}
	}
	for _, t := range l {
		m[i] = t
		i++
	}
	for _, t := range r {
		m[i] = t
		i++
	}
	return m
}

var _ hiter.SliceLike[any] = sliceAdapter[any]{}

type sliceAdapter[T any] []T

func (s sliceAdapter[T]) At(i int) T {
	return s[i]
}

func (s sliceAdapter[T]) Len() int {
	return len(s)
}

func main() {
	rng := mathiter.Rng(20)
	fmt.Printf("merge sort: %t\n",
		slices.IsSorted(mergeSortFunc(slices.Collect(limit(rng, 10)), cmp.Compare)),
	)
	fmt.Printf(
		"merge sort iter: %t\n",
		slices.IsSorted(
			slices.Collect(
				hiter.MergeSort(slices.Collect(limit(rng, 10))),
			),
		),
	)
	fmt.Printf(
		"merge sort atter: %t\n",
		slices.IsSorted(
			slices.Collect(
				hiter.MergeSortSliceLike(sliceAdapter[int](slices.Collect(limit(rng, 10)))),
			),
		),
	)
	fmt.Printf(
		"merge sort atter logically concatenated: %t\n",
		slices.IsSorted(
			slices.Collect(
				hiter.MergeSortSliceLike(
					hiter.ConcatSliceLike(
						slices.Collect(
							xiter.Map(
								func(i int) hiter.SliceLike[int] {
									return sliceAdapter[int](slices.Collect(limit(rng, i)))
								},
								xiter.Limit(rng, 5),
							),
						)...,
					),
				),
			),
		),
	)
}
Output:

merge sort: true
merge sort iter: true
merge sort atter: true
merge sort atter logically concatenated: true

func MergeSortFunc added in v0.0.11

func MergeSortFunc[S ~[]T, T any](m S, cmp func(l, r T) int) iter.Seq[T]

MergeSortFunc is like MergeSort but uses comparison function.

func MergeSortSliceLike added in v0.0.11

func MergeSortSliceLike[S SliceLike[T], T cmp.Ordered](s S) iter.Seq[T]

MergeSortSliceLike is like MergeSort that uses SliceLike interface instead of []T. This implementation is quite experimental. Basically you do not want to use this since it is much, much less performant.

func MergeSortSliceLikeFunc added in v0.0.11

func MergeSortSliceLikeFunc[S SliceLike[T], T any](s S, cmp func(l, r T) int) iter.Seq[T]

MergeSortSliceLikeFunc is like MergeSortSliceLike but uses comparison function instead.

func Min added in v0.0.14

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

Min returns the minimum value of seq. Min returns the zero value if seq is empty.

func MinFunc added in v0.0.14

func MinFunc[V any](fn func(x, y V) int, seq iter.Seq[V]) V

MinFunc returns the minimum value of seq using comparison function fn. fn must return -1 if x is less than y, 0 if x equals y, and +1 x is greater than y (as cmp.Compare does.) MinFunc returns the zero value if seq is empty.

func Nexter added in v0.0.14

func Nexter[
	T any,
	Nexter interface {
		Next() bool
		Err() error
	},
](n Nexter, scanner func(Nexter) (T, error)) iter.Seq2[T, error]

Nexter returns an iterator over Nexter implementation, e.g. sql.Rows, or even sqlx.Rows.

func Nth added in v0.0.14

func Nth[V any](n int, seq iter.Seq[V]) (v V, ok bool)

Nth returns the nth element from seq by yielding up to n+1 elements. n is a 0-indexed number. Passing 0 as n returns the first element. Nth returns zero values if n is less than 0 or greater than or equals to the length of the iterator.

func Nth2 added in v0.0.14

func Nth2[K, V any](n int, seq iter.Seq2[K, V]) (k K, v V, ok bool)

Nth2 returns the nth pair from seq by yielding up to n+1 pairs. n is a 0-indexed number. Passing 0 as n returns the first element. Nth2 returns zero values if n is less than 0 or greater than or equals to the length of the iterator.

func Omit

func Omit[K any](seq iter.Seq[K]) func(yield func() bool)

Omit returns an iterator over seq but drops data seq yields.

func Omit2

func Omit2[K, V any](seq iter.Seq2[K, V]) func(yield func() bool)

Omit2 returns an iterator over seq but drops data seq yields.

func OmitF

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

OmitF drops former part of key-value pairs that seq generates.

func OmitL

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

OmitL drops latter part of key-value pairs that seq generates.

func Once added in v0.0.14

func Once[V any](v V) iter.Seq[V]

Once adapts a single value as an iterator; the iterator yields v and stops.

func Once2 added in v0.0.14

func Once2[K, V any](k K, v V) iter.Seq2[K, V]

Once2 adapts a single k-v pair as an iterator; the iterator yields k, v and stops.

func Pairs

func Pairs[K, V any](seq1 iter.Seq[K], seq2 iter.Seq[V]) iter.Seq2[K, V]

Pairs combines seq1 and seq2 into an iterator over key-value pairs. If either stops, the returned iterator stops.

func Permutations added in v0.0.11

func Permutations[S ~[]E, E any](in S) iter.Seq[S]

Permutations returns an iterator that yields permutations of in. The returned iterator reorders in in-place. The caller should not retain in or slices from the iterator, Or should explicitly clone yielded values.

Example
package main

import (
	"fmt"

	"github.com/ngicks/go-iterator-helper/hiter"
)

func main() {
	in := []int{1, 2, 3}
	for p := range hiter.Permutations(in) {
		fmt.Printf("%#v\n", p)
	}
}
Output:

[]int{1, 2, 3}
[]int{2, 1, 3}
[]int{3, 1, 2}
[]int{1, 3, 2}
[]int{2, 3, 1}
[]int{3, 2, 1}

func Range

func Range[T Numeric](start, end T) iter.Seq[T]

Range returns an iterator over sequential Numeric values in the half-open interval [start, end). Values start from `start` and step toward `end`. At each step value is increased by 1 if start < end, otherwise decreased by 1.

Example (Prevent_off_by_one)
package main

import (
	"fmt"

	"github.com/ngicks/go-iterator-helper/hiter"
	"github.com/ngicks/go-iterator-helper/x/exp/xiter"
)

func main() {
	for i := range hiter.LimitUntil(
		func(i int) bool { return i < 50 },
		xiter.Map(
			func(i int) int { return i * 7 },
			hiter.Range(0, 10),
		),
	) {
		if i > 0 {
			fmt.Printf(" ")
		}
		fmt.Printf("%d", i)
	}
}
Output:

0 7 14 21 28 35 42 49

func RangeInclusive added in v0.0.14

func RangeInclusive[T Numeric](start, end T, includeStart, includeEnd bool) iter.Seq[T]

RangeInclusive is like Range but also allows control over inclusiveness. Set both includeStart and includeEnd true if the range should be in the interval [start, end].

func ReduceGroup added in v0.0.11

func ReduceGroup[K comparable, V, Sum any](
	reducer func(accumulator Sum, current V) Sum,
	initial Sum,
	seq iter.Seq2[K, V],
) map[K]Sum

ReduceGroup sums up values from seq for every unique keys separately, then collects pairs of key and converted value into a new map and returns it. initial is passed once for every unique keys to reducer.

Example
package main

import (
	"encoding/json"
	"fmt"
	"maps"

	"github.com/ngicks/go-iterator-helper/hiter"
	"github.com/ngicks/go-iterator-helper/x/exp/xiter"
)

func main() {
	m1 := map[int]string{
		0: "foo",
		1: "bar",
		2: "baz",
	}
	m2 := map[int]string{
		0: "foo",
		2: "zab",
		3: "gooood",
	}

	reduced := hiter.ReduceGroup(
		func(sum []string, c string) []string { return append(sum, c) },
		nil,
		xiter.Concat2(maps.All(m1), maps.All(m2)),
	)

	bin, _ := json.MarshalIndent(reduced, "", "    ")

	fmt.Printf("%s\n", bin)
}
Output:

{
    "0": [
        "foo",
        "foo"
    ],
    "1": [
        "bar"
    ],
    "2": [
        "baz",
        "zab"
    ],
    "3": [
        "gooood"
    ]
}

func Repeat

func Repeat[V any](v V, n int) iter.Seq[V]

Repeat returns an iterator over v repeated n times. If n < 0, the returned iterator repeats forever.

func Repeat2

func Repeat2[K, V any](k K, v V, n int) iter.Seq2[K, V]

Repeat2 returns an iterator over the pair of k and v repeated n times. If n < 0, the returned iterator repeats forever.

func RepeatFunc added in v0.0.3

func RepeatFunc[V any](fnV func() V, n int) iter.Seq[V]

RepeatFunc returns an iterator that generates result from fnV n times. If n < 0, the returned iterator repeats forever.

func RepeatFunc2 added in v0.0.3

func RepeatFunc2[K, V any](fnK func() K, fnV func() V, n int) iter.Seq2[K, V]

RepeatFunc2 returns an iterator that generates result of fnK and fnV n times. If n < 0, the returned iterator repeats forever.

func Replace added in v0.0.16

func Replace[V comparable](old, new V, n int, seq iter.Seq[V]) iter.Seq[V]

Replace is ReplaceFunc where matcher f tests if k equals old.

func Replace2 added in v0.0.16

func Replace2[K, V comparable](
	oldK K, oldV V, newK K, newV V,
	n int,
	seq iter.Seq2[K, V],
) iter.Seq2[K, V]

Replace2 is ReplaceFunc2 where matcher f tests if k-v pair equals pair of oldK, oldV.

func ReplaceFunc added in v0.0.16

func ReplaceFunc[V any](f func(V) bool, new V, n int, seq iter.Seq[V]) iter.Seq[V]

ReplaceFunc returns an iterator over seq but the first n values that matches f is replaced with new. If n < 0, there is no limit on the number of replacements.

func ReplaceFunc2 added in v0.0.16

func ReplaceFunc2[K, V any](
	f func(K, V) bool,
	newK K, newV V,
	n int,
	seq iter.Seq2[K, V],
) iter.Seq2[K, V]

ReplaceFunc2 returns an iterator over seq but the first n key-value pairs that matches f is replaced with new. If n < 0, there is no limit on the number of replacements.

func RunningReduce added in v0.0.11

func RunningReduce[V, Sum any](
	reducer func(accumulator Sum, current V, i int) Sum,
	initial Sum,
	seq iter.Seq[V],
) iter.Seq[Sum]

RunningReduce returns an iterator over every intermediate reducer results.

Example
package main

import (
	"fmt"
	"math"

	"github.com/ngicks/go-iterator-helper/hiter"
)

func main() {
	for i, r := range hiter.Enumerate(
		hiter.RunningReduce(
			func(accum int64, next int64, idx int) int64 { return accum + next },
			int64(0),
			hiter.Range[int64](1, math.MaxInt64),
		),
	) {
		if i >= 5 {
			break
		}
		fmt.Printf("%d\n", r)
	}
}
Output:

1
3
6
10
15

func Skip

func Skip[V any](n int, seq iter.Seq[V]) iter.Seq[V]

Skip returns an iterator over seq that skips n elements from seq.

func Skip2

func Skip2[K, V any](n int, seq iter.Seq2[K, V]) iter.Seq2[K, V]

Skip2 returns an iterator over seq that skips n key-value pairs from seq.

func SkipLast added in v0.0.5

func SkipLast[V any](n int, seq iter.Seq[V]) iter.Seq[V]

SkipLast returns an iterator over seq that skips last n elements of seq.

Example
package main

import (
	"fmt"

	"github.com/ngicks/go-iterator-helper/hiter"
)

func main() {
	fmt.Print("Without SkipLast: ")
	first := true
	for i := range hiter.Range(0, 10) {
		if !first {
			fmt.Print(", ")
		}
		fmt.Printf("%d", i)
		first = false
	}
	fmt.Println()
	fmt.Print("With SkipLast:    ")

	first = true
	for i := range hiter.SkipLast(5, hiter.Range(0, 10)) {
		if !first {
			fmt.Print(", ")
		}
		fmt.Printf("%d", i)
		first = false
	}
	fmt.Println()
}
Output:

Without SkipLast: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
With SkipLast:    0, 1, 2, 3, 4

func SkipLast2 added in v0.0.5

func SkipLast2[K, V any](n int, seq iter.Seq2[K, V]) iter.Seq2[K, V]

SkipLast2 returns an iterator over seq that skips last n key-value pairs of seq.

func SkipWhile

func SkipWhile[V any](f func(V) bool, seq iter.Seq[V]) iter.Seq[V]

SkipWhile returns an iterator over seq that skips elements until f returns false.

func SkipWhile2

func SkipWhile2[K, V any](f func(K, V) bool, seq iter.Seq2[K, V]) iter.Seq2[K, V]

SkipWhile2 returns an iterator over seq that skips key-value pairs until f returns false.

func Step added in v0.0.14

func Step[N Numeric](initial, step N) iter.Seq[N]

Step returns an iterator over numerics values starting from initial and added step at each step. The iterator iterates forever. The caller might want to limit it by Limit.

func StepBy added in v0.0.14

func StepBy[V any](initial, step int, v []V) iter.Seq2[int, V]

StepBy returns an iterator over pair of index and value associated the index. The index starts from initial and steps by step.

func Sum added in v0.0.11

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

func SumOf added in v0.0.11

func SumOf[V any, S Summable](selector func(ele V) S, seq iter.Seq[V]) S

func Tap added in v0.0.7

func Tap[V any](tap func(V), seq iter.Seq[V]) iter.Seq[V]

Tap returns an iterator over seq without any modification to values from seq. tap is called against every value from seq to observe values. For purpose of Tap, the tap callback function should not retain arguments.

Example
package main

import (
	"fmt"

	"github.com/ngicks/go-iterator-helper/hiter"
)

func main() {
	for i := range hiter.Tap(
		func(i int) {
			fmt.Printf("observed: %d\n", i)
		},
		hiter.Range(1, 4),
	) {
		fmt.Printf("yielded:  %d\n", i)
	}
}
Output:

observed: 1
yielded:  1
observed: 2
yielded:  2
observed: 3
yielded:  3

func Tap2 added in v0.0.7

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

Tap2 returns an iterator over seq without any modification to pairs from seq. tap is called against every pair from seq to observe pairs. For purpose of Tap, the tap callback function should not retain arguments.

func TapLast added in v0.0.16

func TapLast[V any](tap func(), seq iter.Seq[V]) iter.Seq[V]

TapLast returns an iterator over values from seq. tap is executed after all values from seq are consumed without breaking it.

Experimental: not tested and might be changed any time.

func TapLast2 added in v0.0.16

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

TapLast2 returns an iterator over key-value pairs from seq. tap is executed after all pairs from seq are consumed without breaking it.

Experimental: not tested and might be changed any time.

func ToKeyValue added in v0.0.13

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

ToKeyValue converts iter.Seq2[K, V] into iter.Seq[KeyValue[K, V]]. This functions is particularly useful when sending values from iter.Seq2[K, V] through some data transfer mechanism that only allows data to be single value, e.g. channels.

func Transpose

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

Transpose returns an iterator over seq that yields K and V reversed.

func TryAppendSeq added in v0.0.14

func TryAppendSeq[S ~[]E, E any](s S, seq iter.Seq2[E, error]) (S, error)

TryAppendSeq is like slices.AppendSeq but stops collecting at the first error and returns the extended result before the error.

func TryCollect added in v0.0.14

func TryCollect[E any](seq iter.Seq2[E, error]) ([]E, error)

TryCollect is like slices.Collect but stops collecting at the first error and returns the extended result before the error.

func TryFind added in v0.0.14

func TryFind[V any](f func(V) bool, seq iter.Seq2[V, error]) (v V, idx int, err error)

TryFind is like FindFunc but stops if seq yields non-nil error.

func TryForEach added in v0.0.14

func TryForEach[V any](f func(V), seq iter.Seq2[V, error]) error

TryForEach is like ForEach but returns an error if seq yields non-nil error.

func TryReduce added in v0.0.14

func TryReduce[Sum, V any](f func(Sum, V) Sum, sum Sum, seq iter.Seq2[V, error]) (Sum, error)

TryReduce is like xiter.Reduce but returns an error if seq yields non-nil error.

func Unify added in v0.0.14

func Unify[K, V, U any](fn func(K, V) U, seq iter.Seq2[K, V]) iter.Seq[U]

Unify unifies key-value pairs from seq into single values by applying fn to convert iter.Seq2[K, V] to iter.Seq[U].

func Unique added in v0.0.16

func Unique[V comparable](seq iter.Seq[V]) iter.Seq[V]

Unique is UniqueFunc where the value itself is an identifier.

func Unique2 added in v0.0.16

func Unique2[K, V comparable](seq iter.Seq2[K, V]) iter.Seq2[K, V]

Unique2 is UniqueFunc2 where the key-value pair itself is an identifier.

func UniqueFunc added in v0.0.16

func UniqueFunc[V any, I comparable](f func(V) I, seq iter.Seq[V]) iter.Seq[V]

UniqueFunc returns an iterator over every unique values from seq. f returns unique identifiers for v.

Unlike Compact, UniqueFunc buffers ids. Therefore the larger cardinality, the more memory is consumed.

func UniqueFunc2 added in v0.0.16

func UniqueFunc2[K, V any, I comparable](f func(K, V) I, seq iter.Seq2[K, V]) iter.Seq2[K, V]

UniqueFunc2 returns an iterator over every unique key-value pairs from seq. f returns unique identifiers for combination of k and v.

Unlike Compact2, UniqueFunc2 buffers ids. Therefore the larger cardinality, the more memory is consumed.

func Values2 added in v0.0.14

func Values2[S ~[]KeyValue[K, V], K, V any](s S) iter.Seq2[K, V]

Values2 returns an iterator that yields the KeyValue slice elements in order.

func Window

func Window[S ~[]E, E any](s S, n int) iter.Seq[S]

Window returns an iterator over overlapping sub-slices of n size (moving windows). n must be a positive non zero value. Values from the iterator are always slices of n size. The iterator yields nothing when it is not possible.

Example (Moving_average)
package main

import (
	"fmt"
	"slices"

	"github.com/ngicks/go-iterator-helper/hiter"
	"github.com/ngicks/go-iterator-helper/x/exp/xiter"
)

func main() {
	src := []int{1, 0, 1, 0, 1, 0, 5, 3, 2, 3, 4, 6, 5, 3, 6, 7, 7, 8, 9, 5, 7, 7, 8}
	first := true
	for avg := range xiter.Map(
		func(s []int) float64 {
			return float64(hiter.Sum(slices.Values(s))) / float64(len(s))
		},
		hiter.Window(src, 5),
	) {
		if !first {
			fmt.Print(", ")
		}
		fmt.Printf("%02.1f", avg)
		first = false
	}
	fmt.Println()
}
Output:

0.6, 0.4, 1.4, 1.8, 2.2, 2.6, 3.4, 3.6, 4.0, 4.2, 4.8, 5.4, 5.6, 6.2, 7.4, 7.2, 7.2, 7.2, 7.2

func WindowSeq added in v0.0.13

func WindowSeq[V any](n int, seq iter.Seq[V]) iter.Seq[iter.Seq[V]]

WindowSeq allocates n sized buffer and fills it with values from seq in FIFO-manner. Once the buffer is full, the returned iterator yields iterator over buffered values each time value is yielded from the input seq.

n must be a positive non zero value. Each iterator yields exact n size of values. If seq yields less than n, the iterator yields nothing.

Example (Moving_average)
package main

import (
	"fmt"
	"iter"
	"slices"

	"github.com/ngicks/go-iterator-helper/hiter"
	"github.com/ngicks/go-iterator-helper/x/exp/xiter"
)

func main() {
	src := []int{1, 0, 1, 0, 1, 0, 5, 3, 2, 3, 4, 6, 5, 3, 6, 7, 7, 8, 9, 5, 7, 7, 8}
	first := true
	for avg := range xiter.Map(
		func(s iter.Seq[int]) float64 {
			return float64(hiter.Sum(s)) / float64(5)
		},
		hiter.WindowSeq(5, slices.Values(src)),
	) {
		if !first {
			fmt.Print(", ")
		}
		fmt.Printf("%02.1f", avg)
		first = false
	}
	fmt.Println()
}
Output:

0.6, 0.4, 1.4, 1.8, 2.2, 2.6, 3.4, 3.6, 4.0, 4.2, 4.8, 5.4, 5.6, 6.2, 7.4, 7.2, 7.2, 7.2, 7.2

func WithGroupId added in v0.0.16

func WithGroupId[V any, I comparable](f func(V) I, seq iter.Seq[V]) iter.Seq2[int, V]

WithGroupId returns an iterator over pair of unique index for the group id and value from seq. f determines unique group identifiers that corresponds the input value. WithGroupId buffers all group ids f returns, then converts its appearance order.

Types

type Atter added in v0.0.6

type Atter[T any] interface {
	At(i int) T
}

type FuncIterable

type FuncIterable[V any] func() iter.Seq[V]

func (FuncIterable[V]) IntoIter

func (f FuncIterable[V]) IntoIter() iter.Seq[V]

func (FuncIterable[V]) Iter

func (f FuncIterable[V]) Iter() iter.Seq[V]

type FuncIterable2

type FuncIterable2[K, V any] func() iter.Seq2[K, V]

func (FuncIterable2[K, V]) IntoIter2

func (f FuncIterable2[K, V]) IntoIter2() iter.Seq2[K, V]

func (FuncIterable2[K, V]) Iter2

func (f FuncIterable2[K, V]) Iter2() iter.Seq2[K, V]

type GoGroup added in v0.0.14

type GoGroup interface {
	Go(f func() error)
	Wait() error
}

type IntoIterable

type IntoIterable[V any] interface {
	IntoIter() iter.Seq[V]
}

IntoIterable wraps basic IntoIter2 method.

IntoIter might return non-pure / stateful iterators, which would also mutate internal state of implementation. Therefore calling the method or invoking the returned iterator multiple times might yield different data without replaying them.

type IntoIterable2

type IntoIterable2[K, V any] interface {
	IntoIter2() iter.Seq2[K, V]
}

IntoIterable2 wraps basic IntoIter2 method.

IntoIter2 might return non-pure / stateful iterators, which would also mutate internal state of implementation. Therefore calling the method or invoking the returned iterator multiple times might yield different data without replaying them.

type Iterable

type Iterable[V any] interface {
	Iter() iter.Seq[V]
}

Iterable wraps basic Iter method.

Iter should always return pure / stateless iterators, which always generates same set of data.

type Iterable2

type Iterable2[K, V any] interface {
	Iter2() iter.Seq2[K, V]
}

Iterable2 wraps basic Iter2 method.

Iter2 should always return pure / stateless iterators, which always generates same set of pairs.

type KeyValue

type KeyValue[K, V any] struct {
	K K
	V V
}

func Collect2

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

Collect2 collects values from seq into a new KeyValue slice and returns it.

type KeyValues

type KeyValues[K, V any] []KeyValue[K, V]

KeyValues adds the Iter2 method to slice of KeyValue-s.

Example

Useful for test data.

package main

import (
	"fmt"

	"github.com/ngicks/go-iterator-helper/hiter"
)

func main() {
	kv := hiter.KeyValues[string, string]{{"foo", "bar"}, {"baz", "qux"}, {"quux", "corge"}}

	for k, v := range kv.Iter2() {
		fmt.Printf("%s:%s\n", k, v)
	}
}
Output:

foo:bar
baz:qux
quux:corge

func (KeyValues[K, V]) Iter2

func (v KeyValues[K, V]) Iter2() iter.Seq2[K, V]

type Lenner added in v0.0.16

type Lenner interface {
	Len() int
}

type Numeric

type Numeric interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
		~float32 | ~float64
}

type SeqIterable added in v0.0.16

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

func WrapSeqIterable added in v0.0.16

func WrapSeqIterable[V any](seq iter.Seq[V]) SeqIterable[V]

WrapSeqIterable wraps seq into SeqIterable[V].

This is here only for type inference; less typing, easy auto-fill.

func (SeqIterable[V]) IntoIter added in v0.0.16

func (f SeqIterable[V]) IntoIter() iter.Seq[V]

func (SeqIterable[V]) Iter added in v0.0.16

func (f SeqIterable[V]) Iter() iter.Seq[V]

type SeqIterable2 added in v0.0.16

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

func WrapSeqIterable2 added in v0.0.16

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

WrapSeqIterable2 wraps seq into SeqIterable2[V].

This is here only for type inference; less typing, easy auto-fill.

func (SeqIterable2[K, V]) IntoIter2 added in v0.0.16

func (f SeqIterable2[K, V]) IntoIter2() iter.Seq2[K, V]

func (SeqIterable2[K, V]) Iter2 added in v0.0.16

func (f SeqIterable2[K, V]) Iter2() iter.Seq2[K, V]

type SliceLike added in v0.0.11

type SliceLike[T any] interface {
	Atter[T]
	Len() int
}

func ConcatSliceLike added in v0.0.11

func ConcatSliceLike[T any](s ...SliceLike[T]) SliceLike[T]

ConcatSliceLike logically concatenates SliceLike[T] implementations to form a single concatenated SliceLike[T].

type Summable added in v0.0.11

type Summable interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
		~float32 | ~float64 |
		~complex64 | ~complex128 |
		~string
}

as per https://go.dev/ref/spec#arithmetic_operators

Directories

Path Synopsis
The package async defines asynchronous adapters.
The package async defines asynchronous adapters.
bufioiter defines iterator source/collector that corresponds to std library `bufio`.
bufioiter defines iterator source/collector that corresponds to std library `bufio`.
containeriter defines iterator source/collector that corresponds to std library `container/*`.
containeriter defines iterator source/collector that corresponds to std library `container/*`.
cryptoiter defines iterator source/collector that corresponds to std `crypto/*`.
cryptoiter defines iterator source/collector that corresponds to std `crypto/*`.
databaseiter defines iterator source/collector that corresponds to std library `database/*`.
databaseiter defines iterator source/collector that corresponds to std library `database/*`.
encodingiter defines iterator source/collector that corresponds to std library `encoding` and all its descendants (`encoding/*`)
encodingiter defines iterator source/collector that corresponds to std library `encoding` and all its descendants (`encoding/*`)
errbox boxes iter.Seq[V, error] and converts to iter.Seq[V].
errbox boxes iter.Seq[V, error] and converts to iter.Seq[V].
internal
ioiter defines iterator source/collector that corresponds to std library `io/*`.
ioiter defines iterator source/collector that corresponds to std library `io/*`.
Wrapper for iterable objects; heap, list, ring, slice, map, channel, etc.
Wrapper for iterable objects; heap, list, ring, slice, map, channel, etc.
iterreader defines functions that converts an iterator to io.Reader.
iterreader defines functions that converts an iterator to io.Reader.
package mapper is collection of small mapping helpers.
package mapper is collection of small mapping helpers.
mathiter defines iterator source/collector that corresponds to std `math/*`.
mathiter defines iterator source/collector that corresponds to std `math/*`.
reflectiter defines iterator source/collector that corresponds to std library `reflect`.
reflectiter defines iterator source/collector that corresponds to std library `reflect`.
stringsiter defines iterator source/collector that corresponds to std library `strings`.
stringsiter defines iterator source/collector that corresponds to std library `strings`.

Jump to

Keyboard shortcuts

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