xiter

package module
v0.0.0-...-9fc873a Latest Latest
Warning

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

Go to latest
Published: Feb 15, 2024 License: MIT Imports: 8 Imported by: 0

README

xiter

Go Reference

xiter is a very simple implementation of iterator utility functions for Go's rangefunc GOEXPERIMENT introduced in Go 1.22. It is primarily intended to make it easier to play around with that experiment and not for actual usage. Although the module's functionality is compatible with the new experiment, all of its features should work just fine with a plain Go toolchain and should even work with any older version of Go that supports generics (1.18+).

Note that due to the lack of generic type aliases, this package's Seq type and the standard library's iter.Seq type need to be manually converted between. This should hopefully be resolved in Go 1.23. See https://github.com/golang/go/issues/46477.

Documentation

Overview

Package xiter provides iterator-related functionality compatible with, but not requiring, Go 1.22 and GOEXPERIMENT=rangefunc.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func All

func All[T any](seq Seq[T], f func(T) bool) bool

All returns true if f(element) is true for every element of seq.

func Any

func Any[T any](seq Seq[T], f func(T) bool) bool

Any returns true if f(element) is true for any elements of seq.

func AppendSplitTo

func AppendSplitTo[T1, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2)

AppendSplitTo collects the elements of seq by appending them to existing slices.

func AppendTo

func AppendTo[T any, S ~[]T](seq Seq[T], s S) S

AppendTo appends the values of seq to s, returning the new slice.

func Collect

func Collect[T any](seq Seq[T]) []T

Collect returns a slice of the elements of seq.

func CollectSize

func CollectSize[T any](seq Seq[T], len int) []T

CollectSize pre-allocates the slice being collected into to the given size. It is provided purely for convenience.

func CollectSplit

func CollectSplit[T1, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2)

CollectSplit is like Collect, but for a SplitSeq.

func Contains

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

Contains returns true if v is an element of seq.

func Drain

func Drain[T any](seq Seq[T])

Drain empties seq, discarding every single value and returning once it's finished.

func Equal

func Equal[T cmp.Ordered](seq1, seq2 Seq[T]) bool

Equal returns true if seq1 and seq2 are the same length and each element of each is equal to the element at the same point in the sequence of the other.

func EqualFunc

func EqualFunc[T1, T2 any](seq1 Seq[T1], seq2 Seq[T2], equal func(T1, T2) bool) bool

EqualFunc is like Equal but uses a custom comparison function to determine the equivalence of the elements of each sequence.

func Find

func Find[T any](seq Seq[T], f func(T) bool) (r T, ok bool)

Find returns the first value of seq for which f(value) returns true.

func Fold

func Fold[T any](seq Seq[T], reducer func(T, T) T) T

Fold performs a Reduce but uses the first value yielded by seq instead of a provided initial value. If seq doesn't yield any values, the zero value of T is returned.

func GoPull

func GoPull[T any](seq Seq[T]) (iter func() (T, bool), stop func())

GoPull simulates a pull-iterator using Go's built-in concurrency primitives in lieu of coroutines. It handles all synchronization internally, so, despite running the iterator in a new thread, there shouldn't be any data races, but there is some performance overhead.

The returned stop function must be called when the iterator is no longer in use.

func IsSorted

func IsSorted[T cmp.Ordered](seq Seq[T]) bool

IsSorted returns true if each element of seq is greater than or equal to the previous one.

func IsSortedFunc

func IsSortedFunc[T any](seq Seq[T], compare func(T, T) int) bool

IsSortedFunc is like IsSorted but uses a custom comparison function.

func Max

func Max[T cmp.Ordered](seq Seq[T]) T

Max returns maximum element yielded by seq or the zero value if seq doesn't yield anything.

func Min

func Min[T cmp.Ordered](seq Seq[T]) T

Min returns the minimum element yielded by seq or the zero value if seq doesn't yield anything.

func Partition

func Partition[T any](seq Seq[T], f func(T) bool) (true, false []T)

Partition returns two slices, one containing all of the elements of seq for which f(element) is true and one containing all of those for which it is false.

func PartitionInto

func PartitionInto[T any](seq Seq[T], f func(T) bool, true, false []T) ([]T, []T)

PartitionInto performs a Partition by appending to two existing slices.

func Product

func Product[T Multiplyable](seq Seq[T]) T

Product returns the values of seq multiplied together. It returns 1 if no values are yielded.

func Pull

func Pull[T any](seq Seq[T]) (iter func() (T, bool), stop func())

func Reduce

func Reduce[T, R any](seq Seq[T], initial R, reducer func(R, T) R) R

Reduce calls reducer on each value of seq, passing it initial as its first argument on the first call and then the result of the previous call for each call after that. It returns the final value returned by reducer.

Reduce can be somewhat complicated to get the hang of, but very powerful. For example, a simple summation of values can be done as

sum := Reduce(seq, 0, func(total, v int) int { return total + v })

func SendContext

func SendContext[T any](seq Seq[T], ctx context.Context, c chan<- T)

SendContext sends values from seq to c repeatedly until either the sequence ends or ctx is canceled. It blocks until one of those two things happens.

func Sum

func Sum[T Addable](seq Seq[T]) T

Sum returns the values of seq added together in the order that they are yielded.

Types

type Addable

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

Addable is a type that should probably exist in the standard library somewhere because it's quite command and kind of a pain to write every time I need it.

type Multiplyable

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

type Pair

type Pair[T1, T2 any] struct {
	V1 T1
	V2 T2
}

Pair contains two values of arbitrary types.

func P

func P[T1, T2 any](v1 T1, v2 T2) Pair[T1, T2]

P returns a Pair containing v1 and v2.

func (Pair[T1, T2]) Split

func (p Pair[T1, T2]) Split() (T1, T2)

Split is a convenience function that just returns the two values contained in the pair.

type Seq

type Seq[T any] func(yield func(T) bool)

Seq represents an iterator over a sequence of values. When called, the passed yield function is called for each successive value. Returning false from yield causes the iterator to stop, equivalent to a break statement.

func Bytes

func Bytes(s string) Seq[byte]

Bytes returns a Seq over the bytes of s.

func Cache

func Cache[T any](seq Seq[T]) Seq[T]

Cache returns a Seq that can be iterated more than once. On the first iteration, it yields the values from seq and caches them. On subsequent iterations, it yields the cached values from the first iteration.

func Chunks

func Chunks[T any](seq Seq[T], n int) Seq[[]T]

Chunks works just like Windows except that the yielded slices of elements do not overlap. In other words,

Chunks(Generate(0, 1), 3)

will yield

[0, 1, 2]
[3, 4, 5]
[6, 7, 8]

Like with Windows, the slice is reused between iterations.

func Concat

func Concat[T any](seqs ...Seq[T]) Seq[T]

Concat creates a new Seq that yields the values of each of the provided Seqs in turn.

func Filter

func Filter[T any](seq Seq[T], f func(T) bool) Seq[T]

Filter returns a Seq that yields only the values of seq for which f(value) returns true.

func Flatten

func Flatten[T any](seq Seq[Seq[T]]) Seq[T]

Flatten yields all of the elements of each Seq yielded from seq in turn.

func Generate

func Generate[T Addable](start, step T) Seq[T]

Generate returns a Seq that first yields start and then yields successive values by adding step to the previous continuously. The returned Seq does not end. To limit it to a specific number of returned elements, use Limit.

func Handle

func Handle[T any](seq Seq2[T, error], f func(error) bool) Seq[T]

Handle splits seq by calling f for any non-nil errors yielded by seq. If f returns false, iteration stops. If an iteration's error is nil or f returns true, the other value is yielded by the returned Seq.

TODO: This is significantly less useful than it could be. For example, there's no way to tell it to skip the yield but continue iteration anyways.

func Limit

func Limit[T any](seq Seq[T], n int) Seq[T]

Limit returns a Seq that yields at most n values from seq.

func Map

func Map[T1, T2 any](seq Seq[T1], f func(T1) T2) Seq[T2]

Map returns a Seq that yields the values of seq transformed via f.

func MapKeys

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

MapKeys returns a Seq over the keys of m.

func MapValues

func MapValues[K comparable, V any, M ~map[K]V](m M) Seq[V]

MapValues returns a Seq over the values of m.

func Merge

func Merge[T cmp.Ordered](seq1, seq2 Seq[T]) Seq[T]

Merge returns a sequence that yields values from the ordered sequences seq1 and seq2 one at a time to produce a new ordered sequence made up of all of the elements of both seq1 and seq2.

func MergeFunc

func MergeFunc[T any](seq1, seq2 Seq[T], compare func(T, T) int) Seq[T]

MergeFunc is like Merge, but uses a custom comparison function for determining the order of values.

func Of

func Of[T any](vals ...T) Seq[T]

Of returns a Seq that yields the provided values.

func OfChan

func OfChan[T any](c <-chan T) Seq[T]

OfChan returns a Seq which yields values received from c. The sequence ends when c is closed. It is equivalent to range c.

func OfSlice

func OfSlice[T any, S ~[]T](s S) Seq[T]

OfSlice returns a Seq over the elements of s. It is equivalent to range s with the index ignored.

func Or

func Or[T any](seqs ...Seq[T]) Seq[T]

Or yields all of the values from the first Seq which yields at least one value and then stops.

func RecvContext

func RecvContext[T any](ctx context.Context, c <-chan T) Seq[T]

RecvContext returns a Seq that receives from c continuously until either c is closed or the given context is canceled.

func Runes

func Runes[T ~[]byte | ~string](s T) Seq[rune]

Runes returns a Seq over the runes of s.

func Skip

func Skip[T any](seq Seq[T], n int) Seq[T]

Skip returns a Seq that skips over the first n elements of seq and then yields the rest normally.

func StringSplit

func StringSplit(s, sep string) Seq[string]

StringSplit returns an iterator over the substrings of s that are separated by sep. It behaves very similarly to strings.Split.

func ToPair

func ToPair[T1, T2 any](seq Seq2[T1, T2]) Seq[Pair[T1, T2]]

ToPair takes a two-value iterator and produces a single-value iterator of pairs.

func V1

func V1[T1, T2 any](seq Seq2[T1, T2]) Seq[T1]

V1 returns a Seq which iterates over only the T1 elements of seq.

func V2

func V2[T1, T2 any](seq Seq2[T1, T2]) Seq[T2]

V2 returns a Seq which iterates over only the T2 elements of seq.

func Windows

func Windows[T any](seq Seq[T], n int) Seq[[]T]

Windows returns a slice over successive overlapping portions of size n of the values yielded by seq. In other words,

Windows(Generate(0, 1), 3)

will yield

[0, 1, 2]
[1, 2, 3]
[2, 3, 4]

and so on. The slice yielded is reused from one iteration to the next, so it should not be held onto after each iteration has ended. Map and slices.Clone may come in handy for dealing with situations where this is necessary.

func Zip

func Zip[T1, T2 any](seq1 Seq[T1], seq2 Seq[T2]) Seq[Zipped[T1, T2]]

Zip returns a new Seq that yields the values of seq1 and seq2 simultaneously.

type Seq2

type Seq2[T1, T2 any] func(yield func(T1, T2) bool)

Seq2 represents a two-value iterator.

func Enumerate

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

Enumerate returns a Seq2 that counts the number of iterations of seq as it yields elements from it, starting at 0.

func FromPair

func FromPair[T1, T2 any](seq Seq[Pair[T1, T2]]) Seq2[T1, T2]

FromPair converts a Seq of pairs to a two-value Seq.

func OfMap

func OfMap[K comparable, V any, M ~map[K]V](m M) Seq2[K, V]

OfMap returns a Seq over the key-value pairs of m.

func OfSliceIndex

func OfSliceIndex[T any, S ~[]T](s S) Seq2[int, T]

OfSliceIndex returns a Seq over the elements of s. It is equivalent to range s.

func OfValue

OfValue returns a Seq2 that iterates over any iterable type using reflection. If the type is one which only produces a single value per iteration, such as a channel, the second value yielded each iteration will just be reflect.Value{}.

type SplitSeq

type SplitSeq[T1, T2 any] func(y1 func(T1) bool, y2 func(T2) bool)

A SplitSeq is like a Seq but can yield via either of two functions. It might not be useful, but is included anyways because it might be.

func Split

func Split[T any](seq Seq[T], f func(T) bool) SplitSeq[T, T]

Split returns a SplitSeq which yields the values of seq for which f(value) is true to its first yield function and the rest to its second.

func Split2

func Split2[T1, T2 any](seq Seq2[T1, T2]) SplitSeq[T1, T2]

Split2 transforms a Seq2 into a SplitSeq. Every iteration of the Seq2 yields both values via the SplitSeq.

type Zipped

type Zipped[T1, T2 any] struct {
	V1  T1
	OK1 bool

	V2  T2
	OK2 bool
}

Zipped holds values from an iteration of a Seq returned by Zip.

Jump to

Keyboard shortcuts

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