itertools

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jan 17, 2023 License: MIT Imports: 6 Imported by: 1

README

itertools

Project status GoDoc License

Go Iteration tools with a rusty flavour

Requirements

  • Go 1.18+

Motivation

  1. I missed some iteration style tools in Rust.
  2. Wanted to see how far I could push Go generics(turns out it is very limited).
  3. For fun.

Example Usage (Simple)

package main

import (
	"fmt"
	"github.com/go-playground/itertools"
)

func main() {
	results := itertools.WrapSlice([]int{4, 3, 2, 1, 0}).Iter().Filter(func(v int) bool {
		if v >= 5 {
			return true
		}
		return false
	}).Collect()

	fmt.Printf("%#v\n", results)
}

Example Usage (Complex)

See examples for more complex usages.

package main

import (
	"fmt"
	"github.com/go-playground/itertools"
	optionext "github.com/go-playground/pkg/v5/values/option"
	"strconv"
)

type FakeIterator struct {
	max int
}

func (f *FakeIterator) Next() optionext.Option[int] {
	f.max--
	if f.max < 0 {
		return optionext.None[int]()
	}
	return optionext.Some(f.max)
}

func main() {
	results := itertools.WrapSliceMap[int, string]([]int{4, 3, 2, 1, 0}).Iter().Chain(&FakeIterator{
		max: 10,
	}).Filter(func(v int) bool {
		if v >= 5 {
			return true
		}
		return false
	}).StepBy(2).Take(6).Map(func(v int) string {
		return strconv.Itoa(v)
	}).Iter().Collect()

	fmt.Printf("%#v\n", results)
}

Caveats

  • Map and it's MAP type parameter must be defined and passed around to be able to using inline. This is a limitation of Go generics not allowing new type parameters on methods.
  • Chunk can only be used at the end of a series of iterators from Iter but can be used and wrapped by Iter again. This is a limitation of the Go Compiler which causes a recursive initialization issue https://github.com/golang/go/issues/50215.
  • Iter must be called on some types, like the wrapped slice or map types, to allow usage of helper functions tied directly to them but not Iterate
  • Reduce will have to be used directly instead of other helper function such as Sum, Product, ... again because no new type parameters on methods.

How to Contribute

Make a pull request... can't guarantee it will be added, going to strictly vet what goes in.

License

Distributed under MIT License, please see license file within the code for more details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Chain

func Chain[T any, FI Iterator[T], SI Iterator[T]](first FI, second SI) *chainIterator[T, FI, SI, struct{}]

Chain creates a new `chainIterator[T]` for use.

func ChainWithMap

func ChainWithMap[T any, FI Iterator[T], SI Iterator[T], MAP any](first FI, second SI) *chainIterator[T, FI, SI, MAP]

ChainWithMap creates a new `chainIterator[T]` for use and parameter to specify a Map type for the `Iterate.Map` helper function.

func Chunk

func Chunk[T any, I Iterator[T]](iterator I, size int) chunker[T, I, struct{}]

Chunk creates a new `chunker` for use.

The default Map type is struct{}, see `ChunkWithMap` for details.

func ChunkWithMap

func ChunkWithMap[T any, I Iterator[T], MAP any](iterator I, size int) chunker[T, I, MAP]

ChunkWithMap creates a new `chunker` for use that accepts a Map type for use with `Iterate`.

func Filter

func Filter[T any, I Iterator[T]](iterator I, fn FilterFn[T]) *filterIterator[T, I, struct{}]

Filter creates a new `filterIterator`.

func FilterWithMap

func FilterWithMap[T any, I Iterator[T], MAP any](iterator I, fn FilterFn[T]) *filterIterator[T, I, MAP]

FilterWithMap creates a new `filterIterator` for use which also specifies a potential future `Map` operation.

func Map

func Map[T any, I Iterator[T], MAP any](iterator I, fn MapFn[T, MAP]) mapper[T, I, MAP]

Map creates a new iterator for transformation of types.

func Peekable

func Peekable[T any, I Iterator[T]](iterator I) *peekableIterator[T, I]

Peekable accepts and `Iterator[T]` and turns it into a Peekable iterator.

NOTE: Peekable iterators are commonly the LAST in a chain of iterators.

func StepBy

func StepBy[T any, I Iterator[T]](iterator I, step int) *stepByIterator[T, I, struct{}]

StepBy returns a `stepByIterator[T]` for use.

func StepByWithMap

func StepByWithMap[T any, I Iterator[T], MAP any](iterator I, step int) *stepByIterator[T, I, MAP]

StepByWithMap returns a `stepByIterator[T]` for use and can specify a future `Map` type conversion.

func Take

func Take[T any, I Iterator[T]](iterator I, n int) *takeIterator[T, I, struct{}]

Take creates a new `takeIterator[T]` for use.

func TakeWhile

func TakeWhile[T any, I Iterator[T]](iterator I, fn TakeWhileFn[T]) takeWhileIterator[T, I, struct{}]

TakeWhile creates a new `takeWhileIterator[T,I]` for use.

func TakeWhileWithMap

func TakeWhileWithMap[T any, I Iterator[T], MAP any](iterator Iterator[T], fn TakeWhileFn[T]) takeWhileIterator[T, I, MAP]

TakeWhileWithMap creates a new `takeWhileIterator[T,I]` for use and can specify a future `Map` type conversion.

func TakeWithMap

func TakeWithMap[T any, I Iterator[T], MAP any](iterator I, n int) *takeIterator[T, I, MAP]

TakeWithMap creates a new `takeIterator[T]` for use and can specify a future `Map` type conversion.

func WrapMap

func WrapMap[K comparable, V any](m map[K]V) mapWrapper[K, V, struct{}]

WrapMap creates a new iterator for transformation of types.

func WrapMapWithMap

func WrapMapWithMap[K comparable, V, MAP any](m map[K]V) mapWrapper[K, V, MAP]

WrapMapWithMap creates a new `mapWrapper` for use which also specifies a potential future `Map` operation.

func WrapSlice

func WrapSlice[T any](slice []T) sliceWrapper[T, struct{}]

WrapSlice accepts and turns a sliceWrapper into an iterator.

The default the Map type to struct{} when none is required. See WrapSliceMap if one is needed.

func WrapSliceMap

func WrapSliceMap[T, MAP any](slice []T) sliceWrapper[T, MAP]

WrapSliceMap accepts and turns a sliceWrapper into an iterator with a map type specified for IterPar() to allow the Map helper function.

Types

type Entry

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

Entry represents a single Map entry.

type FilterFn

type FilterFn[T any] func(v T) bool

FilterFn represents the `filterIterator` function.

type Iterate

type Iterate[T any, I Iterator[T], MAP any] struct {
	// contains filtered or unexported fields
}

Iterate is an iterator with attached helper functions

func Iter

func Iter[T any, I Iterator[T]](iterator I) Iterate[T, I, struct{}]

Iter creates a new iterator with helper functions.

It defaults the Map() function to struct{}. Use IterMap() if you wish to specify a type.

func IterMap

func IterMap[T any, I Iterator[T], MAP any](iterator I) Iterate[T, I, MAP]

IterMap creates a new iterator with helper functions.

It accepts a map type `MAP` to allow for usage of the `Map` and `CollectMap` helper function inline. You must use the Map() function standalone otherwise.

func (Iterate[T, I, MAP]) All

func (i Iterate[T, I, MAP]) All(fn func(T) bool) (isAll bool)

All returns true if all element matches the function return, false otherwise.

func (Iterate[T, I, MAP]) AllParallel

func (i Iterate[T, I, MAP]) AllParallel(fn func(T) bool) (isAll bool)

AllParallel returns true if all element matches the function return, false otherwise.

This will run in parallel. It is recommended to only use this when the overhead of running n parallel is less than the work needing to be done.

func (Iterate[T, I, MAP]) Any

func (i Iterate[T, I, MAP]) Any(fn func(T) bool) (isAny bool)

Any returns true if any element matches the function return, false otherwise.

func (Iterate[T, I, MAP]) AnyParallel

func (i Iterate[T, I, MAP]) AnyParallel(fn func(T) bool) (isAny bool)

AnyParallel returns true if any element matches the function return, false otherwise.

This will run in parallel. It is recommended to only use this when the overhead of running n parallel is less than the work needing to be done.

func (Iterate[T, I, MAP]) Chain

func (i Iterate[T, I, MAP]) Chain(iterator Iterator[T]) Iterate[T, Iterator[T], MAP]

Chain creates a new chainIterator for use.

func (Iterate[T, I, MAP]) Chunk

func (i Iterate[T, I, MAP]) Chunk(size int) chunker[T, Iterator[T], MAP]

Chunk returns a `*Iterate[T, V]` the returns an []T of the specified size

The last slice is not guaranteed to be the exact chunk size when iterator finishes the remainder is returned.

func (Iterate[T, I, MAP]) Collect

func (i Iterate[T, I, MAP]) Collect() (results []T)

Collect transforms an iterator into a sliceWrapper.

This will run in parallel is using a parallel iterator.

func (Iterate[T, I, MAP]) CollectIter

func (i Iterate[T, I, MAP]) CollectIter() sliceWrapper[T, MAP]

CollectIter transforms an iterator into a sliceWrapper and returns a *sliceWrapper in order to run additional functions inline such as Sort().

eg. .Filter(...).CollectIter().Sort(...).WrapSlice()

This will run in parallel is using a parallel iterator.

func (Iterate[T, I, MAP]) Count

func (i Iterate[T, I, MAP]) Count() (j int)

Count consumes the iterator and returns count if iterations.

This will run in parallel is using a parallel iterator.

func (Iterate[T, I, MAP]) CountParallel

func (i Iterate[T, I, MAP]) CountParallel() int

CountParallel consumes the iterator concurrently and returns count if iterations.

func (Iterate[T, I, MAP]) Filter

func (i Iterate[T, I, MAP]) Filter(fn FilterFn[T]) Iterate[T, Iterator[T], MAP]

Filter accepts a `FilterFn[T]` to filter items.

func (Iterate[T, I, MAP]) Find

func (i Iterate[T, I, MAP]) Find(fn func(T) bool) (result optionext.Option[T])

Find searches for the next element of an iterator that satisfies the function.

func (Iterate[T, I, MAP]) ForEach

func (i Iterate[T, I, MAP]) ForEach(fn func(T))

ForEach runs the provided function for each element until completion.

This will run in parallel is using a parallel iterator.

func (Iterate[T, I, MAP]) ForEachParallel

func (i Iterate[T, I, MAP]) ForEachParallel(fn func(T))

ForEachParallel runs the provided function for each element in parallel until completion.

The function must maintain its own thread safety.

func (Iterate[T, I, MAP]) Map

func (i Iterate[T, I, MAP]) Map(fn MapFn[T, MAP]) mapper[T, Iterator[T], MAP]

Map accepts a `FilterFn[T]` to filter items.

NOTE: This is made possible by passing the one-time possible MAP type around. This is unfortunate but the only way it can be supported due to the limitations of the Go Compiler.

Since it's a likely function to be used inline it has been done this way for convenience.

func (Iterate[T, I, MAP]) Next

func (i Iterate[T, I, MAP]) Next() optionext.Option[T]

Next returns the new iterator value

func (Iterate[T, I, MAP]) Partition

func (i Iterate[T, I, MAP]) Partition(fn func(v T) bool) (left, right []T)

Partition creates two collections from supplied function, all elements returning true will be in one result and all that were returned false in the other.

func (Iterate[T, I, MAP]) PartitionIter

func (i Iterate[T, I, MAP]) PartitionIter(fn func(v T) bool) (left, right sliceWrapper[T, struct{}])

PartitionIter creates two iterable collections from supplied function, all elements returning true will be in one result and all that were returned false in the other.

func (Iterate[T, I, MAP]) Peekable

func (i Iterate[T, I, MAP]) Peekable() *peekableIterator[T, Iterator[T]]

Peekable returns a `PeekableIterator[T]` that wraps the current iterator.

NOTE: Peekable iterators are commonly the LAST in a chain of iterators.

func (Iterate[T, I, MAP]) Position

func (i Iterate[T, I, MAP]) Position(fn func(T) bool) optionext.Option[int]

Position searches for an element in an iterator, returning its index.

func (Iterate[T, I, MAP]) Reduce

func (i Iterate[T, I, MAP]) Reduce(fn func(accum T, current T) T) optionext.Option[T]

Reduce reduces the elements to a single one, by repeatedly applying a reducing function.

func (Iterate[T, I, MAP]) StepBy

func (i Iterate[T, I, MAP]) StepBy(step int) Iterate[T, Iterator[T], MAP]

StepBy returns a `Iterate[T, V]` starting at the same point, but stepping by the given amount at each iteration.

The first element is always returned before the stepping begins.

func (Iterate[T, I, MAP]) Take

func (i Iterate[T, I, MAP]) Take(n int) Iterate[T, Iterator[T], MAP]

Take yields elements until n elements are yielded or the end of the iterator is reached (whichever happens first)

func (Iterate[T, I, MAP]) TakeWhile

func (i Iterate[T, I, MAP]) TakeWhile(fn TakeWhileFn[T]) Iterate[T, Iterator[T], MAP]

TakeWhile yields elements while the function return true or the end of the iterator is reached (whichever happens first)

type Iterator

type Iterator[T any] interface {
	// Next advances the iterator and returns the next value.
	//
	// Returns an Option with value of None when iteration has finished.
	Next() optionext.Option[T]
}

Iterator is an interface representing something that iterates using the Next method.

type MapFn

type MapFn[T, MAP any] func(v T) MAP

MapFn represents the mapWrapper transformation function.

type PeekableIterator

type PeekableIterator[T any] interface {
	Iterator[T]

	// Peek returns the `Next` element from the `Iterator` without advancing it.
	Peek() optionext.Option[T]
}

PeekableIterator is an interface representing something that iterates using the Next method and ability to `Peek` the next element value without advancing the `Iterator`.

type TakeWhileFn

type TakeWhileFn[T any] func(v T) bool

TakeWhileFn represents the `takeWhileIterator[T]` function.

Jump to

Keyboard shortcuts

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