itertools

package module
v1.0.5 Latest Latest
Warning

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

Go to latest
Published: Feb 21, 2025 License: BSD-3-Clause Imports: 1 Imported by: 0

README

Itertools GoDoc Go Report Card Go build and tests

Tools and libraries to deal with iterators in Go > 1.23.

This aims to be a polished collection of tools to manipulate iterators in Go.

Iterators have been introduced in Go 1.23 and we'll likely soon get some helpers and APIs in the standard library to create and mutate them.

If you are eager to use operations like Map or Filter or would like a more idiomatic API for bufio.Scanner this module is probably for you.

I'll make sure that, as soon as standard alternatives become available, I'll deprecate my versions and facilitate the migration to the new ones (e.g. providing tools to automatically rewrite code).

Subpackages

If you need to construct or consume iterators please use the from and to subpackages.

Notes

I am not endorsing a programming style that encourages mapreduce-like code and that pushes for a higher mental overhead than it's necessary.

This library is intended to help when those operations are actually needed to make code easier to read, but I would invite the reader of this document to try and avoid creating obscure code bases that rely too heavily on this library.

Documentation

Overview

Package itertools provides operators for iterators.

For functions that consume or create operators please check the from and to packages in this module.

Guarantees

All operators are guaranteed to:

  • run in linear time
  • allocate constant memory
  • depend only on the iter and constraints packages
  • not spawn additional goroutines

Operators that cannot be implemented within these constraint will be added to a separate packages.

Idiomatic Use

Go tends to be a very clear language that favors readability over compact code. All users of this library should try their best to preserve this property when manipulating iterators.

The suggested way to do so is to name intermediate iterators when a manipulation chain is implemented instead of nesting calls.

Example:

numbersTo4 := slices.Values([]int{1,2,3,4})
odds := Filter(numbers, func(i int) bool {
	return i%2 != 0
})
doubled := Map(odds, func(i int) int {
	return i*2
})
result := slices.Collect(doubled)

Is preferable to a call chain like:

result := slices.Collect(Map(Filter(slices.Values([]int{...

If the same combination of operators is used more than twice it's strongly advised to create helper functions with telling names.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Concat

func Concat[T any](srcs ...iter.Seq[T]) iter.Seq[T]

Concat emits all values from the provided sources, in order.

func Deduplicate

func Deduplicate[T comparable](src iter.Seq[T]) iter.Seq[T]

Deduplicate removes duplicates emitted by src. It doesn't check that the entire iterator never emits two identical values, it just removes consecutive identical values.

func EmptyValues added in v1.0.4

func EmptyValues[T any](src iter.Seq[T]) iter.Seq2[T, empty]

EmptyValues promotes the iterator to a Seq2 with empty values. This can be used as a helper to populate a map used as a set or any other iter consumer that doesn't use the values but still requires a Seq2.

func Entries

func Entries[K, V any](src iter.Seq2[K, V]) iter.Seq[struct {
	K K
	V V
}]

Entries emits couples of values that represent the key-value pairs from the source iterator.

func Filter

func Filter[T any](src iter.Seq[T], predicate func(T) (ok bool)) iter.Seq[T]

Filter emits the item that the predicate returns true for.

func Filter2

func Filter2[K, V any](src iter.Seq2[K, V], predicate func(K, V) (ok bool)) iter.Seq2[K, V]

Filter2 is like Filter for Seq2.

func Flatten

func Flatten[T any](src iter.Seq[iter.Seq[T]]) iter.Seq[T]

Flatten emits all values emitted by the inner iterators, flattening the source iterator structure to be one layer.

func Flatten2

func Flatten2[K, V any](src iter.Seq2[K, iter.Seq[V]]) iter.Seq2[K, V]

Flatten2 emits all values emitted by the inner iterators, flattening the source iterator structure to be one layer. Keys for inner iterators are repeated for every inner emission.

func FlattenSlice

func FlattenSlice[T any](src iter.Seq[[]T]) iter.Seq[T]

FlattenSlice is like Flatten for iterators of slices.

func Keys

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

Keys emits the keys, or first items of every couple emitted by the source iterator.

func Map

func Map[T, V any](src iter.Seq[T], predicate func(T) V) iter.Seq[V]

Map applies the predicate to the source iterator until either source is exhausted or the consumer stops the iteration.

func Map12

func Map12[T, K, V any](src iter.Seq[T], predicate func(T) (K, V)) iter.Seq2[K, V]

Map12 is like Map but it transforms the iterator from Seq to Seq2.

func Map2

func Map2[K1, V1, K2, V2 any](src iter.Seq2[K1, V1], predicate func(K1, V1) (K2, V2)) iter.Seq2[K2, V2]

Map2 is like Map for iter.Seq2.

func Map21

func Map21[K, V, T any](src iter.Seq2[K, V], predicate func(K, V) T) iter.Seq[T]

Map21 is like Map but it transforms the iterator from Seq2 to Seq.

func PairWise

func PairWise[T any](src iter.Seq[T]) iter.Seq2[T, T]

PairWise emits all values with the value that preceded them. This means all values will be emitted twice except for the first and last one. Values are emitted once as the second value, then as the first, in this order. Pairs can be imagined as a sliding window on the source iterator.

func SkipN

func SkipN[T any](src iter.Seq[T], n int) iter.Seq[T]

SkipN discards the first n items of the source iterator and forwards the remaining items. This can be seen as a slice operation such as myIterator[n:].

func SkipUntil

func SkipUntil[T any](src iter.Seq[T], predicate func(T) (ok bool)) iter.Seq[T]

SkipUntil discards all values until predicate returns true for the first time. Then it stops calling predicate and forwards the first accepted value and all the remaining ones.

func TakeN

func TakeN[T any](src iter.Seq[T], n int) iter.Seq[T]

TakeN emits the first n items of the source iterator. This can be seen as a slice operation such as myIterator[:n+1].

func TakeWhile

func TakeWhile[T any](src iter.Seq[T], predicate func(T) (ok bool)) iter.Seq[T]

TakeWhile mirrors the source iterator while predicate returns true, and stops at the first false.

func Tap

func Tap[T any](src iter.Seq[T], peek func(T)) iter.Seq[T]

Tap calls peek for all values emitted by src and consumed by the returned Seq.

Peek must not modify or keep a reference to the values it observes.

func Values

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

Values emits the values, or second items of every couple emitted by the source iterator.

func Zip

func Zip[T, V any](src1 iter.Seq[T], src2 iter.Seq[V]) iter.Seq2[T, V]

Zip emits every time both source iterators have emitted a value, thus generating couples of values where no source value is used more than once and no one is discarded except for the trailing ones after one of the sources has stopped generating values.

Types

This section is empty.

Directories

Path Synopsis
exp
meta
Package meta is experimental and tries to create an iteration API that allows for piping and composition by offering transformation constructors.
Package meta is experimental and tries to create an iteration API that allows for piping and composition by offering transformation constructors.
Package to provides utilities to deconstruct or consume iterators down to other types or values.
Package to provides utilities to deconstruct or consume iterators down to other types or values.

Jump to

Keyboard shortcuts

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