iters

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2025 License: Apache-2.0 Imports: 5 Imported by: 0

README

Go iterator helper suite

Go Reference Go Report Card codecov

Type safe Stream processing library inspired in the Gosequence library, which at the same time is heavily inspired in the Java Streams API.

Table of contents

Requirements

  • Go 1.24 or higher

Usage examples

Example 1: basic creation, transformation and iteration
  1. Creates a literal iter.Seq containing all the integers from 1 to 11.
  2. From the sequence, selects all the integers that are prime
  3. Iterates the sequence. For each filtered int, prints a message.
import (
  "fmt"
  "github.com/mariomac/iters"
)

func main() {
    numbers := iters.OfRange(1, 12)
    
    for n := range iters.Filter(numbers, isPrime) {
        fmt.Printf("%d is a prime number\n", n)
    }
}

func isPrime(n int) bool {
  for i := 2; i <= n/2; i++ {
    if n%i == 0 {
      return false
    }
  }
  return true
}

Output:

1 is a prime number
2 is a prime number
3 is a prime number
5 is a prime number
7 is a prime number
11 is a prime number

Alternatively, you can use the ForEach method to iterate the sequence in a functional way:

iters.ForEach(prime, func(n int) {
    fmt.Printf("%d is a prime number\n", n)
})
Example 2: generation, map, limit and slice conversion
  1. Creates an infinite sequence of random integers (no problem, the generated sequences are evaluated lazily!)
  2. Divides the random integer to get a number between 1 and 6
  3. Limits the infinite sequence to 5 elements.
  4. Collects the sequence items as a slice.
rnd := rand.New(rand.NewSource(time.Now().UnixMilli()))
fmt.Println("let me throw 5 times a dice for you")

results := iters.Map(
    iters.Generate(rnd.Int),
    func(n int) int {
        return n%6 + 1
    },
)
takeFive := iters.Limit(5, results)

fmt.Printf("results: %v\n",
	slices.Collect(takeFive))

Output:

let me throw 5 times a dice for you
results: [3 5 2 1 3]
Example 3: Generation from an iterator, Map to a different type
  1. Generates an infinite sequence composed by 1, double(1), double(double(1)), etc... and cut it to 6 elements.
  2. Maps the numbers' sequence to a strings' sequence.
  3. Converts the words sequence to a slice and prints it.
func main() {
    numbers := iters.Iterate(1, double)
    sixNums := iters.Limit(6, numbers)
    words := iters.Map(sixNums, asWord)
    
    fmt.Println(slices.Collect(words))
}

func double(n int) int {
    return 2 * n
}

func asWord(n int) string {
    if n < 10 {
        return []string{"zero", "one", "two", "three", "four", "five",
            "six", "seven", "eight", "nine"}[n]
    } else {
        return "many"
    }
}

Output:

[one two four eight many many]
Example 4: deduplication of elements

Following example requires to compare the elements of the iter.Seq, so the iter.Seq needs to be composed by comparable elements (this is, accepted by the the == and != operators):

  1. Instantiate an iter.Seq of comparable items.
  2. Pass it to the Distinct method, that will return a copy of the original iter.Seq without duplicates
  3. Operating as any other sequence.
words := iters.Distinct(
    iters.Of("hello", "hello", "!", "ho", "ho", "ho", "!"),
)

fmt.Printf("Deduplicated words: %v\n", slices.Collect(words))

Output:

Deduplicated words: [hello ! ho]
Example 5: Reduce
  1. Generate an incremental sequence from 1 to 8, both included.
  2. Reduce all the elements multiplying them
// create a sequence in range [1, 8]
seq := iters.OfRange(1, 9)
// multiply each item in the limited sequence
fac8, _ := iters.Reduce(seq8, func(a, b int) int {
    return a * b
})
fmt.Println("The factorial of 8 is", fac8)

Output:

The factorial of 8 is 40320

Extra credits

This library is a port of the Gostream library from the same author, adopted to work directly with the Go 1.23 iter.Seq and iter.Seq2 without intermediate types.

The Gostream processing and aggregation functions, and thus most of the functions of this library, are heavily inspired in the Java Stream Specification.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AllMatch

func AllMatch[T any](input iter.Seq[T], predicate func(T) bool) bool

AllMatch returns whether all elements of this iter.Seq match the provided predicate. If this operation finds an item where the predicate is false, it stops processing the rest of the iter.Seq.

func AnyMatch

func AnyMatch[T any](input iter.Seq[T], predicate func(T) bool) bool

AnyMatch returns whether any elements of the iter.Seq match the provided predicate. If this operation finds an item where the predicate is true, it stops processing the rest of the iter.Seq.

func Concat

func Concat[T any](a, b iter.Seq[T]) iter.Seq[T]

Concat creates a lazily concatenated iter.Seq whose elements are all the elements of the first iter.Seq followed by all the elements of the second iter.Seq.

func Count

func Count[T any](input iter.Seq[T]) int

Count of elements in the iter.Seq.

func Distinct

func Distinct[T comparable](input iter.Seq[T]) iter.Seq[T]

Distinct returns an iter.Seq consisting of the distinct elements (according to equality operator) of the input iter.Seq. This function needs to internally store the previous distinct elements in memory, so it might not be suitable for large or infinite sequences with high variability in their items.

func Empty

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

Empty returns an empty iter.Seq

func Filter

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

Filter returns a iter.Seq consisting of the items of this input iter.Seq that match the given predicate (this is, applying the predicate function over the item returns true).

func FindFirst

func FindFirst[T any](input iter.Seq[T]) (T, bool)

FindFirst returns the first element of this iter.Seq along with true or, if the iter.Seq is empty, the zero value of the inner type along with false.

func FlatMap

func FlatMap[IN, OUT any](input iter.Seq[IN], mapper func(IN) iter.Seq[OUT]) iter.Seq[OUT]

FlatMap returns an iter.Seq consisting of the results of replacing each element of the input iter.Seq with the contents of a mapped iter.Seq produced by applying the provided mapping function to each element. Each mapped iter.Seq is closed after its contents have been placed into this iter.Seq. (If a mapped iter.Seq is null an empty iter.Seq is used, instead.)

Due to the lazy nature of sequences, if any of the mapped sequences is infinite, some operations (Count, Reduce, Sorted, AllMatch...) will not end.

When both the input and output type are the same, the operation can be invoked as the method input.FlatMap(mapper).

func ForEach

func ForEach[T any](input iter.Seq[T], consumer func(T))

ForEach invokes the consumer function for each item of the iter.Seq.

func ForEach2

func ForEach2[T1, T2 any](input iter.Seq2[T1, T2], consumer func(T1, T2))

ForEach2 invokes the consumer function for each pair of items of the iter.Seq2

func Generate

func Generate[T any](supplier func() T) iter.Seq[T]

Generate an infinite iter.Seq where each element is generated by the provided supplier function. Due to the potential statefulness of the supplier, multiple operations towards the same iter.Seq might provide different results.

This creates a lazy sequence. The supplier won't be called until it is requested for consumption by the transformation or aggregation functions.

Caution! Unless you limit the lenght of the iter.Seq (e.g. using the Limit function), the aggregation functions over this iter.Seq might not terminate.

func Iterate

func Iterate[T any](seed T, f func(T) T) iter.Seq[T]

Iterate returns an infinite sequential ordered iter.Seq produced by iterative application of a function f to an initial element seed, producing a iter.Seq consisting of seed, f(seed), f(f(seed)), etc. The first element (position 0) in the iter.Seq will be the provided seed. For n > 0, the element at position n, will be the result of applying the function f to the element at position n - 1. Due to the stateful nature of the supplier, multiple operations towards the same iter.Seq might provide different results.

func Keys

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

Keys returns an iter.Seq that iterates the keys (first/left items) of the source iter.Seq2

func Limit

func Limit[T any](maxSize int, input iter.Seq[T]) iter.Seq[T]

Limit returns an iter.Seq consisting of the elements of the input iter.Seq, truncated to be no longer than maxSize in length.

func Limit2 added in v0.2.0

func Limit2[K, V any](maxSize int, input iter.Seq2[K, V]) iter.Seq2[K, V]

Limit2 returns an iter.Seq2 consisting of the elements of the input iter.Seq2, truncated to be no longer than maxSize in length.

func Map

func Map[IT, OT any](input iter.Seq[IT], mapper func(IT) OT) iter.Seq[OT]

Map returns a iter.Seq consisting of the results of individually applying the mapper function to each elements of the input iter.Seq.

func Max

func Max[T cmp.Ordered](input iter.Seq[T]) (T, bool)

Max returns the maximum element of the iter.Seq. along with true if the iter.Seq is not empty. If the iter.Seq is empty, returns the zero value along with false.

func MaxFunc

func MaxFunc[T any](input iter.Seq[T], cmp func(a, b T) int) (T, bool)

MaxFunc returns the maximum element of the iter.Seq according to the provided Comparator, along with true if the iter.Seq is not empty. If the iter.Seq is empty, returns the zero value along with false.

func Min

func Min[T cmp.Ordered](input iter.Seq[T]) (T, bool)

Min returns the minimum element of the iter.Seq, along with true if the iter.Seq is not empty. If the iter.Seq is empty, returns the zero value along with false.

func MinFunc

func MinFunc[T any](input iter.Seq[T], cmp func(a, b T) int) (T, bool)

MinFunc returns the minimum element of the iter.Seq according to the provided Comparator, along with true if the iter.Seq is not empty. If the iter.Seq is empty, returns the zero value along with false.

func NoneMatch

func NoneMatch[T any](input iter.Seq[T], predicate func(T) bool) bool

NoneMatch returns whether no elements of the iter.Seq match the provided predicate. If this operation finds an item where the predicate is true, it stops processing the rest of the iter.Seq.

func Of

func Of[T any](a ...T) iter.Seq[T]

Of returns an iter.Seq that iterates each of the passed arguments in order.

func OfChannel

func OfChannel[T any](ch <-chan T) iter.Seq[T]

OfChannel returns an iter.Seq that iterates over all values received from the provided channel. The iteration continues until the channel is closed. This means that aggregations over the returned iter.Seq might not terminate if the channel is inactive or never closed.

func OfMap

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

OfMap returns an iter.Seq2 that iterates over all key-value pairs of the provided map. It is just an alias for maps.All.

func OfMapKeys

func OfMapKeys[T comparable, K any](m map[T]K) iter.Seq[T]

OfMapKeys returns an iter.Seq that iterates over all keys of the provided map. It is just an alias for maps.Keys.

func OfMapValues

func OfMapValues[T comparable, V any](m map[T]V) iter.Seq[V]

OfMapValues returns an iter.Seq that iterates over all values of the provided map. It is just an alias for maps.Values.

func OfRange

func OfRange[T constraints.Integer](start, excludedEnd T) iter.Seq[T]

OfRange returns an iter.Seq that iterates the integer numbers from the first argument (inclusive) to the second argument (exclusive).

func OfSlice

func OfSlice[T any](sl []T) iter.Seq[T]

OfSlice returns an iter.Seq that iterates over all elements of the provided slice. It is just an alias for slices.Values.

func Peek

func Peek[T any](input iter.Seq[T], consumer func(T)) iter.Seq[T]

Peek peturns an iter.Seq consisting of the elements of the input iter.Seq, additionally performing the provided action on each element as elements are consumed from the resulting iter.Seq.

func Reduce

func Reduce[T any](input iter.Seq[T], accumulator func(a, b T) T) (T, bool)

Reduce performs a reduction on the elements of the input Seq, using an associative accumulation function, and returns a value describing the reduced value, if any. If no reduced value (e.g. because the iter.Seq is empty), the second returned value is false.

func Skip

func Skip[T any](n int, input iter.Seq[T]) iter.Seq[T]

Skip returns an iter.Seq consisting of the remaining elements of the input iter.Seq after discarding the first n elements of the sequence.

func Skip2 added in v0.2.0

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

Skip2 returns an iter.Seq consisting of the remaining elements of the input iter.Seq2 after discarding the first n elements of the sequence.

func Values

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

Values returns an iter.Seq that iterates the values (second/right items) of the source iter.Seq2

func Zip added in v0.2.0

func Zip[K, V any](keys iter.Seq[K], vals iter.Seq[V]) iter.Seq2[K, V]

Zip joins the input iter.Seq[K] and iter.Seq[V] into an iter.Seq2[K, V]. The resulting iter.Seq2 will have the same length as the shorter of the two input iter.Seq.

Types

This section is empty.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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