seq

package
v1.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2025 License: MIT Imports: 7 Imported by: 8

Documentation

Overview

Package seq provides a comprehensive set of utilities for working with sequences in Go applications.

The goal of this package is to offer a rich set of functions for creating, transforming, and consuming iter.Seq, enabling developers to work with collections of data in a functional programming style. The package includes utilities for filtering, mapping, reducing, and sorting sequences, as well as combining and partitioning them.

The package is designed to reduce boilerplate code and improve readability by providing a consistent API for common sequence operations. It leverages Go's type safety and generics to ensure that operations on sequences are both flexible and safe. The Sequence struct is worth mentioning explicitly, allowing method chaining and fluent composition of sequence operations.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Append

func Append[E any](seq iter.Seq[E], elems ...E) iter.Seq[E]

Append appends elements to the end of a sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	initial := seq.Of(1, 2, 3)

	appended := seq.Append(initial, 4, 5, 6)

	result := seq.Collect(appended)

	fmt.Println(result)
}
Output:

[1 2 3 4 5 6]

func Chunk

func Chunk[E any](seq iter.Seq[E], size int) iter.Seq[iter.Seq[E]]

Chunk splits the sequence into chunks of the given size.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5, 6)

	chunks := seq.Chunk(input, 3)

	result := seq.Collect(chunks)

	for _, chunk := range result {
		fmt.Println(seq.Collect(chunk))
	}
}
Output:

[1 2 3]
[4 5 6]

func Collect

func Collect[E any](seq iter.Seq[E]) []E

Collect collects the elements of the given sequence into a slice.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	sequence := seq.Of(1, 2, 3)

	result := seq.Collect(sequence)

	fmt.Println(result)
}
Output:

[1 2 3]

func Concat

func Concat[E any](sequences ...iter.Seq[E]) iter.Seq[E]

Concat concatenates multiple sequences into a single sequence. It also safely handles nil iterators treating them as an empty iterator.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	seq1 := seq.Of(1, 2, 3)
	seq2 := seq.Of(4, 5, 6)

	concatenated := seq.Concat(seq1, seq2, nil)

	result := seq.Collect(concatenated)

	fmt.Println(result)
}
Output:

[1 2 3 4 5 6]

func Contains

func Contains[E comparable](seq iter.Seq[E], elem E) bool

Contains returns true if the element is in the sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	contains := seq.Contains(input, 3)

	fmt.Println(contains)
}
Output:

true

func ContainsAll

func ContainsAll[E comparable](seq iter.Seq[E], elements ...E) bool

ContainsAll returns true if all elements are in the sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	containsAll := seq.ContainsAll(input, 2, 3)

	fmt.Println(containsAll)
}
Output:

true

func Count

func Count[E any](seq iter.Seq[E]) int

Count returns the number of elements in the sequence.

func Cycle

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

Cycle repeats the sequence indefinitely.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3)

	cycled := seq.Cycle(input)

	cycled = seq.Take(cycled, 9) // Limit to 9 elements for demonstration

	result := seq.Collect(cycled)

	fmt.Println(result)
}
Output:

[1 2 3 1 2 3 1 2 3]

func CycleTimes added in v0.29.0

func CycleTimes[E any](seq iter.Seq[E], count int) iter.Seq[E]

CycleTimes repeats the sequence specific number of times.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3)

	cycled := seq.CycleTimes(input, 2)

	cycled = seq.Take(cycled, 9) // Limit to 9 elements for demonstration difference between Cycle and CycleTimes

	result := seq.Collect(cycled)

	fmt.Println(result)
}
Output:

[1 2 3 1 2 3]

func Distinct

func Distinct[E comparable](seq iter.Seq[E]) iter.Seq[E]

Distinct returns a sequence with only unique elements. SQL-like alias for Uniq

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 2, 3, 3, 3)

	distinct := seq.Distinct(input)

	result := seq.Collect(distinct)

	fmt.Println(result)
}
Output:

[1 2 3]

func Each

func Each[E any](seq iter.Seq[E], consumer Consumer[E]) iter.Seq[E]

Each returns a sequence that applies the given consumer to each element of the input sequence and pass it further. Each is an alias for Tap. Comparing to ForEach, this is a lazy function and doesn't consume the input sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	sequence := seq.Each(seq.Of(1, 2, 3), func(v int) {
		fmt.Println(v)
	})

	seq.Flush(sequence)

}
Output:

1
2
3

func Empty added in v0.25.0

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

Empty creates a new empty sequence.

func Every

func Every[E any](seq iter.Seq[E], predicate Predicate[E]) bool

Every returns true if all elements satisfy the predicate.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(2, 4, 6, 8)

	every := seq.Every(input, func(v int) bool { return v%2 == 0 })

	fmt.Println(every)
}
Output:

true

func Exists

func Exists[E any](seq iter.Seq[E], predicate Predicate[E]) bool

Exists returns true if there is at least one element that satisfies the predicate.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	exists := seq.Exists(input, func(v int) bool { return v > 4 })

	fmt.Println(exists)
}
Output:

true

func Filter

func Filter[E any](seq iter.Seq[E], predicate Predicate[E]) iter.Seq[E]

Filter returns a new sequence that contains only the elements that satisfy the predicate.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	filtered := seq.Filter(input, func(v int) bool {
		return v%2 == 0
	})

	result := seq.Collect(filtered)

	fmt.Printf("%v\n", result)
}
Output:

[2 4]

func Find

func Find[E any](seq iter.Seq[E], predicate Predicate[E]) optional.Value[E]

Find returns the first element that satisfies the predicate.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	found := seq.Find(input, func(v int) bool { return v > 3 })

	fmt.Println(found.MustGet())
}
Output:

4

func FindAll

func FindAll[E any](seq iter.Seq[E], predicate Predicate[E]) iter.Seq[E]

FindAll returns all elements that satisfy the predicate.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	found := seq.FindAll(input, func(v int) bool { return v > 3 })

	result := seq.Collect(found)

	fmt.Println(result)
}
Output:

[4 5]

func FindLast

func FindLast[E any](seq iter.Seq[E], predicate Predicate[E]) optional.Value[E]

FindLast returns the last element that satisfies the predicate.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	found := seq.FindLast(input, func(v int) bool { return v > 3 })

	fmt.Println(found.MustGet())
}
Output:

5

func FlatMap

func FlatMap[E any, R any](seq iter.Seq[E], mapper Mapper[E, iter.Seq[R]]) iter.Seq[R]

FlatMap applies a mapper function to each element of the sequence and flattens the result.

Example
package main

import (
	"fmt"
	"iter"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(0, 3)

	flatMapped := seq.FlatMap(input, func(it int) iter.Seq[int] {
		return seq.Of[int](1+it, 2+it, 3+it)
	})

	result := seq.Collect(flatMapped)

	fmt.Println(result)
}
Output:

[1 2 3 4 5 6]

func FlatMapOrErr added in v1.5.0

func FlatMapOrErr[E any, R any](seq iter.Seq[E], mapper func(E) (iter.Seq[R], error)) iter.Seq2[R, error]

FlatMapOrErr transforms each element of a sequence with a mapper, handling errors and flattening nested sequences.

Example
package main

import (
	"fmt"
	"iter"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3)

	mapper := func(v int) (iter.Seq[string], error) {
		if v > 2 {
			return nil, fmt.Errorf("value %d is too large", v)
		}
		return seq.Of(fmt.Sprintf("Number_%d_1", v), fmt.Sprintf("Number_%d_2", v)), nil
	}

	results := seq.FlatMapOrErr(input, mapper)

	for val, err := range results {
		if err != nil {
			fmt.Printf("Error: %v\n", err)
		} else {
			fmt.Printf("Mapped value: %s\n", val)
		}
	}

}
Output:

Mapped value: Number_1_1
Mapped value: Number_1_2
Mapped value: Number_2_1
Mapped value: Number_2_2
Error: value 3 is too large

func FlatMapSlices added in v1.5.0

func FlatMapSlices[E any, R any](seq iter.Seq[E], mapper func(E) []R) iter.Seq[R]

FlatMapSlices transforms each element of the sequence into a slice and flattens the results into a single sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2)

	mapped := seq.FlatMapSlices(input, func(v int) []string {
		return []string{
			fmt.Sprintf("Number_%d_1", v),
			fmt.Sprintf("Number_%d_2", v),
		}
	})

	result := seq.Collect(mapped)

	fmt.Println(result)
}
Output:

[Number_1_1 Number_1_2 Number_2_1 Number_2_2]

func FlatMapSlicesOrErr added in v1.5.0

func FlatMapSlicesOrErr[E any, R any](seq iter.Seq[E], mapper func(E) ([]R, error)) iter.Seq2[R, error]

FlatMapSlicesOrErr transforms elements of a sequence to slices and flattens them, propagating errors from the mapping function.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3)

	mapper := func(v int) ([]string, error) {
		if v > 2 {
			return nil, fmt.Errorf("value %d is too large", v)
		}
		return []string{
			fmt.Sprintf("Number_%d_1", v),
			fmt.Sprintf("Number_%d_2", v),
		}, nil
	}

	results := seq.FlatMapSlicesOrErr(input, mapper)

	for val, err := range results {
		if err != nil {
			fmt.Printf("Error: %v\n", err)
		} else {
			fmt.Printf("Mapped value: %s\n", val)
		}
	}

}
Output:

Mapped value: Number_1_1
Mapped value: Number_1_2
Mapped value: Number_2_1
Mapped value: Number_2_2
Error: value 3 is too large

func Flatten

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

Flatten flattens a sequence of sequences.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(seq.Of(1, 2), seq.Of(3, 4))

	flattened := seq.Flatten(input)

	result := seq.Collect(flattened)

	fmt.Println(result)
}
Output:

[1 2 3 4]

func FlattenSlices added in v0.17.0

func FlattenSlices[Seq iter.Seq[[]E], E any](seq Seq) iter.Seq[E]

FlattenSlices flattens a sequence of slices.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	// Create a sequence of slices
	sequence := seq.Of(1, 2, 3)

	seqOfSlices := seq.Map(sequence, func(n int) []int {
		return []int{n, n + 1}
	})

	// Flatten the sequence of slices
	flattened := seq.FlattenSlices(seqOfSlices)

	// Collect results
	result := seq.Collect(flattened)

	fmt.Println(result)

}
Output:

[1 2 2 3 3 4]

func Flush

func Flush[E any](seq iter.Seq[E])

Flush consumes all elements of the input sequence.

func Fold

func Fold[E any](seq iter.Seq[E], accumulator func(agg E, item E) E) optional.Value[E]

Fold applies a function against an accumulator and each element in the sequence (from left to right) to reduce it to a single value.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of("a", "b", "c")

	sum := seq.Fold(input, func(agg, item string) string {
		return agg + item
	})

	fmt.Println(sum.MustGet())
}
Output:

abc

func FoldRight

func FoldRight[E any](seq iter.Seq[E], accumulator func(agg E, item E) E) optional.Value[E]

FoldRight applies a function against an accumulator and each element in the sequence (from right to left) to reduce it to a single value.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of("a", "b", "c")

	sum := seq.FoldRight(input, func(agg, item string) string {
		return agg + item
	})

	fmt.Println(sum.MustGet())
}
Output:

cba

func ForEach

func ForEach[E any](seq iter.Seq[E], consumer Consumer[E])

ForEach applies consumer to each element of the input sequence. Comparing to Each, this is not a lazy function and consumes the input sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	seq.ForEach(seq.Of(1, 2, 3), func(v int) {
		fmt.Println(v)
	})

}
Output:

1
2
3

func FromSlice

func FromSlice[Slice ~[]E, E any](slice Slice) iter.Seq[E]

FromSlice creates a new sequence from the given slice.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	slice := []int{1, 2, 3}

	sequence := seq.FromSlice(slice)

	result := seq.Collect(sequence)

	fmt.Println(result)
}
Output:

[1 2 3]

func FromSliceReversed added in v0.15.0

func FromSliceReversed[Slice ~[]E, E any](slice Slice) iter.Seq[E]

FromSliceReversed creates a new sequence from the given slice starting from last elements to first. It is more efficient then first creating a seq from slice and then reversing it.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	slice := []int{1, 2, 3}

	sequence := seq.FromSliceReversed(slice)

	result := seq.Collect(sequence)

	fmt.Println(result)
}
Output:

[3 2 1]

func GroupBy

func GroupBy[E any, K comparable](seq iter.Seq[E], by Mapper[E, K]) iter.Seq2[K, iter.Seq[E]]

GroupBy groups the sequence by the given key.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
	"github.com/go-softwarelab/common/pkg/seq2"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5, 6)

	groups := seq.GroupBy(input, func(v int) int {
		return v % 2
	})

	// GroupBy does not guarantee the order of keys, so we sort them for display
	groups = seq2.SortByKeys(groups)
	for k, v := range groups {
		fmt.Printf("%d: %v\n", k, seq.Collect(v))
	}

}
Output:

0: [2 4 6]
1: [1 3 5]

func IsEmpty

func IsEmpty[E any](seq iter.Seq[E]) bool

IsEmpty returns true if the sequence is empty.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3)

	fmt.Println(seq.IsEmpty(input))
}
Output:

false

func IsNotEmpty

func IsNotEmpty[E any](seq iter.Seq[E]) bool

IsNotEmpty returns true if the sequence is not empty.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3)

	isNotEmpty := seq.IsNotEmpty(input)

	fmt.Println(isNotEmpty)
}
Output:

true

func Limit

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

Limit returns a new sequence that contains only the first n elements of the given sequence. SQL-like alias for Take

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	limited := seq.Limit(input, 2)

	result := seq.Collect(limited)

	fmt.Printf("%v\n", result)
}
Output:

[1 2]

func Map

func Map[E any, R any](seq iter.Seq[E], mapper Mapper[E, R]) iter.Seq[R]

Map applies a mapper function to each element of the sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3)

	mapped := seq.Map(input, func(v int) string {
		return fmt.Sprintf("Number_%d", v)
	})

	result := seq.Collect(mapped)

	fmt.Println(result)
}
Output:

[Number_1 Number_2 Number_3]

func MapOrErr added in v0.22.0

func MapOrErr[E any, R any](seq iter.Seq[E], mapper func(E) (R, error)) iter.Seq2[R, error]

MapOrErr applies a mapper function which can return error to each element of the sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3)

	// Example mapper function that returns an error for values > 2
	mapper := func(v int) (string, error) {
		if v > 2 {
			return "", fmt.Errorf("value %d is too large", v)
		}
		return fmt.Sprintf("Number_%d", v), nil
	}

	results := seq.MapOrErr(input, mapper)

	for val, err := range results {
		if err != nil {
			fmt.Printf("Error: %v\n", err)
		} else {
			fmt.Printf("Mapped value: %s\n", val)
		}
	}

}
Output:

Mapped value: Number_1
Mapped value: Number_2
Error: value 3 is too large

func MapTo added in v1.5.0

func MapTo[E any, R1 any, R2 any](seq iter.Seq[E], mapper func(E) (R1, R2)) iter.Seq2[R1, R2]

MapTo transforms an iter.Seq into iter.Seq2 using provided mapper function

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
	"github.com/go-softwarelab/common/pkg/seq2"
)

func main() {
	input := seq.Of(1, 2, 3)

	mapped := seq.MapTo(input, func(v int) (int, string) {
		return v, fmt.Sprintf("Number_%d", v)
	})

	result := seq2.CollectToMap(mapped)

	fmt.Println(result)

}
Output:

map[1:Number_1 2:Number_2 3:Number_3]

func Max

func Max[E types.Ordered](seq iter.Seq[E]) optional.Value[E]

Max returns the maximum element in the sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(2, 3, 1, 5, 4)

	maxVal := seq.Max(input)

	fmt.Println(maxVal.MustGet())
}
Output:

5

func Min

func Min[E types.Ordered](seq iter.Seq[E]) optional.Value[E]

Min returns the minimum element in the sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(2, 3, 1, 5, 4)

	maxVal := seq.Min(input)

	fmt.Println(maxVal.MustGet())
}
Output:

1

func None

func None[E any](seq iter.Seq[E], predicate Predicate[E]) bool

None returns true if no element satisfies the predicate.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	none := seq.None(input, func(v int) bool { return v > 5 })

	fmt.Println(none)
}
Output:

true

func NotContains

func NotContains[E comparable](seq iter.Seq[E], elem E) bool

NotContains returns true if the element is not in the sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	contains := seq.NotContains(input, 3)

	fmt.Println(contains)
}
Output:

false

func Of

func Of[E any](elems ...E) iter.Seq[E]

Of creates a new sequence from the given elements.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	sequence := seq.Of(1, 2, 3)

	result := seq.Collect(sequence)

	fmt.Println(result)
}
Output:

[1 2 3]

func Offset

func Offset[E any](seq iter.Seq[E], n int) iter.Seq[E]

Offset returns a new sequence that skips the first n elements of the given sequence. SQL-like alias for Skip

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	skipped := seq.Offset(input, 2)

	result := seq.Collect(skipped)

	fmt.Printf("%v\n", result)
}
Output:

[3 4 5]

func Partition

func Partition[E any](seq iter.Seq[E], size int) iter.Seq[iter.Seq[E]]

Partition splits the sequence into chunks of the given size.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5, 6)

	partitions := seq.Partition(input, 2)

	result := seq.Collect(partitions)

	for _, partition := range result {
		fmt.Println(seq.Collect(partition))
	}

}
Output:

[1 2]
[3 4]
[5 6]

func PartitionBy

func PartitionBy[E any, K comparable](seq iter.Seq[E], by Mapper[E, K]) iter.Seq[iter.Seq[E]]

PartitionBy splits the sequence into chunks based on the given key. It splits the sequence when ever the key changes, the order matters here.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 1, 5, 6)

	partitions := seq.PartitionBy(input, func(v int) int {
		return (v - 1) / 3
	})

	for partition := range partitions {
		fmt.Println(seq.Collect(partition))
	}
}
Output:

[1 2 3]
[4]
[1]
[5 6]

func PointersFromSlice added in v0.11.0

func PointersFromSlice[Slice ~[]E, E any](slice Slice) iter.Seq[*E]

PointersFromSlice creates a new sequence of pointers for the given slice of value elements.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	slice := []int{1, 2, 3}

	pointersSequence := seq.PointersFromSlice(slice)

	backToValues := seq.Map(pointersSequence, func(p *int) int {
		// NOTE: p is a pointer so no copy is made here
		return *p
	})

	result := seq.Collect(backToValues)
	fmt.Println(result)
}
Output:

[1 2 3]

func Prepend

func Prepend[E any](seq iter.Seq[E], elems ...E) iter.Seq[E]

Prepend prepends elements to the beginning of a sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	initial := seq.Of(4, 5, 6)

	prepended := seq.Prepend(initial, 1, 2, 3)

	result := seq.Collect(prepended)

	fmt.Println(result)
}
Output:

[1 2 3 4 5 6]

func Range

func Range[E types.Integer](start, end E) iter.Seq[E]

Range returns a sequence that yields integers from `start` inclusive to `end` exclusive.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	ranged := seq.Range(0, 5)

	result := seq.Collect(ranged)

	fmt.Println(result)
}
Output:

[0 1 2 3 4]

func RangeTo

func RangeTo[E types.Integer](end E) iter.Seq[E]

RangeTo returns a sequence that yields integers from 0 to `end`.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	ranged := seq.RangeTo(5)

	result := seq.Collect(ranged)

	fmt.Println(result)
}
Output:

[0 1 2 3 4]

func RangeWithStep

func RangeWithStep[E types.Integer](start, end, step E) iter.Seq[E]

RangeWithStep returns a sequence that yields integers from `start` to `end` with `step`.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	ranged := seq.RangeWithStep(0, 10, 2)

	result := seq.Collect(ranged)

	fmt.Println(result)
}
Output:

[0 2 4 6 8]

func Reduce

func Reduce[E any, R any](seq iter.Seq[E], accumulator func(agg R, item E) R, initial R) R

Reduce applies a function against an accumulator and each element in the sequence (from left to right) to reduce it to a single value.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of("a", "b", "c")

	concat := seq.Reduce(input, func(agg, item string) string {
		return agg + item
	}, "")

	fmt.Println(concat)
}
Output:

abc

func ReduceRight

func ReduceRight[E any, R any](seq iter.Seq[E], accumulator func(agg R, item E) R, initial R) R

ReduceRight applies a function against an accumulator and each element in the sequence (from right to left) to reduce it to a single value.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of("a", "b", "c")

	concat := seq.ReduceRight(input, func(agg, item string) string {
		return agg + item
	}, "")

	fmt.Println(concat)
}
Output:

cba

func Repeat

func Repeat[E any, N types.Integer](elem E, count N) iter.Seq[E]

Repeat returns a sequence that yields the same element `count` times.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	repeated := seq.Repeat("hello", 3)

	result := seq.Collect(repeated)

	fmt.Println(result)
}
Output:

[hello hello hello]

func Reverse

func Reverse[E any](seq iter.Seq[E]) iter.Seq[E]

Reverse creates a new sequence that iterates over the elements of the given sequence in reverse order.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	sequence := seq.Of(1, 2, 3)

	reversed := seq.Reverse(sequence)

	result := seq.Collect(reversed)
	fmt.Println(result)
}
Output:

[3 2 1]

func Select

func Select[E any, R any](seq iter.Seq[E], mapper Mapper[E, R]) iter.Seq[R]

Select applies a mapper function to each element of the sequence. SQL-like alias for Map

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3)

	mapped := seq.Select(input, func(v int) string {
		return fmt.Sprintf("Number_%d", v)
	})

	result := seq.Collect(mapped)

	fmt.Println(result)
}
Output:

[Number_1 Number_2 Number_3]

func Skip

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

Skip returns a new sequence that skips the first n elements of the given sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	skipped := seq.Skip(input, 2)

	result := seq.Collect(skipped)

	fmt.Printf("%v\n", result)
}
Output:

[3 4 5]

func SkipUntil

func SkipUntil[E any](seq iter.Seq[E], predicate Predicate[E]) iter.Seq[E]

SkipUntil returns a new sequence that skips elements until the predicate is true.

func SkipWhile

func SkipWhile[E any](seq iter.Seq[E], predicate Predicate[E]) iter.Seq[E]

SkipWhile returns a new sequence that skips elements while the predicate is true.

func Sort

func Sort[E types.Ordered](seq iter.Seq[E]) iter.Seq[E]

Sort sorts the elements of a sequence in ascending order.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5)

	sorted := seq.Sort(input)

	result := seq.Collect(sorted)
	fmt.Println(result)
}
Output:

[1 1 2 3 3 4 5 5 5 6 9]

func SortBy

func SortBy[E any, K types.Ordered](seq iter.Seq[E], keyFn Mapper[E, K]) iter.Seq[E]

SortBy sorts the elements of a sequence in ascending order by the key returned by keyFn.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	type Person struct {
		Name string
		Age  int
	}
	input := seq.Of(
		Person{"Alice", 30},
		Person{"Bob", 25},
		Person{"Charlie", 35},
	)

	sorted := seq.SortBy(input, func(p Person) int {
		return p.Age
	})

	for p := range sorted {
		fmt.Printf("%s (%d)\n", p.Name, p.Age)
	}
}
Output:

Bob (25)
Alice (30)
Charlie (35)

func SortComparing

func SortComparing[E any](seq iter.Seq[E], cmp func(a, b E) int) iter.Seq[E]

SortComparing sorts the elements of a sequence in ascending order using the cmp function.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	type Person struct {
		Name string
		Age  int
	}
	input := seq.Of(
		Person{"Alice", 30},
		Person{"Bob", 25},
		Person{"Charlie", 35},
	)

	sorted := seq.SortComparing(input, func(a, b Person) int {
		return a.Age - b.Age
	})

	for p := range sorted {
		fmt.Printf("%s (%d)\n", p.Name, p.Age)
	}
}
Output:

Bob (25)
Alice (30)
Charlie (35)

func Take

func Take[E any](seq iter.Seq[E], n int) iter.Seq[E]

Take returns a new sequence that contains only the first n elements of the given sequence.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	taken := seq.Take(input, 3)

	result := seq.Collect(taken)

	fmt.Printf("%v\n", result)
}
Output:

[1 2 3]

func TakeUntil

func TakeUntil[E any](seq iter.Seq[E], predicate Predicate[E]) iter.Seq[E]

TakeUntil returns a new sequence that contains elements until the predicate is true.

func TakeWhile

func TakeWhile[E any](seq iter.Seq[E], predicate Predicate[E]) iter.Seq[E]

TakeWhile returns a new sequence that contains elements while the predicate is true.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 2, 1)

	taken := seq.TakeWhile(input, func(v int) bool {
		return v < 3
	})

	result := seq.Collect(taken)

	fmt.Printf("%v\n", result)
}
Output:

[1 2]

func Tap

func Tap[E any](seq iter.Seq[E], consumer func(E)) iter.Seq[E]

Tap returns a sequence that applies the given consumer to each element of the input sequence and pass it further.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	sequence := seq.Tap(seq.Of(1, 2, 3), func(v int) {
		fmt.Println(v)
	})

	seq.Flush(sequence)

}
Output:

1
2
3

func Tick

func Tick(d time.Duration) iter.Seq[time.Time]

Tick returns a sequence that yields the current time every duration.

Example
package main

import (
	"fmt"
	"time"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	ticker := seq.Tick(1 * time.Millisecond)

	ticker = seq.Take(ticker, 5)

	ticker = seq.Tap(ticker, func(v time.Time) {
		fmt.Println(v.Format("15:04:05.000"))
	})

	seq.Flush(ticker)

	// Example Output:
	// 00:00:00.000
	// 00:00:00.001
	// 00:00:00.002
	// 00:00:00.003
	// 00:00:00.004
}

func ToSlice

func ToSlice[Slice ~[]E, E any](seq iter.Seq[E], slice Slice) Slice

ToSlice collects the elements of the given sequence into a slice.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	sequence := seq.Of(1, 2, 3)

	slice := make([]int, 0, 3)
	result := seq.ToSlice(sequence, slice)

	fmt.Println(result)
}
Output:

[1 2 3]

func Union

func Union[E types.Comparable](seq1 iter.Seq[E], seq2 iter.Seq[E]) iter.Seq[E]

Union returns a sequence that contains all distinct elements from both input sequences.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	seq1 := seq.Of(1, 2, 3)
	seq2 := seq.Of(3, 4, 5)

	union := seq.Union(seq1, seq2)

	result := seq.Collect(union)

	fmt.Println(result)
}
Output:

[1 2 3 4 5]

func UnionAll

func UnionAll[E any](seq1 iter.Seq[E], seq2 iter.Seq[E]) iter.Seq[E]

UnionAll returns a sequence that contains all elements from both input sequences.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	seq1 := seq.Of(1, 2, 3)
	seq2 := seq.Of(3, 4, 5)

	unionAll := seq.UnionAll(seq1, seq2)

	result := seq.Collect(unionAll)

	fmt.Println(result)
}
Output:

[1 2 3 3 4 5]

func Uniq

func Uniq[E comparable](seq iter.Seq[E]) iter.Seq[E]

Uniq returns a sequence with only unique elements.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 2, 3, 3, 3)

	unique := seq.Uniq(input)

	result := seq.Collect(unique)

	fmt.Println(result)
}
Output:

[1 2 3]

func UniqBy

func UniqBy[E any, K comparable](seq iter.Seq[E], mapper Mapper[E, K]) iter.Seq[E]

UniqBy returns a sequence with only unique elements based on a key.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of("apple", "banana", "apricot", "blueberry")

	uniqueBy := seq.UniqBy(input, func(v string) string {
		return v[:1] // unique by first letter
	})

	result := seq.Collect(uniqueBy)

	fmt.Println(result)
}
Output:

[apple banana]

func Where

func Where[E any](seq iter.Seq[E], predicate Predicate[E]) iter.Seq[E]

Where returns a new sequence that contains only the elements that satisfy the predicate. SQL-like alias for Filter

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	input := seq.Of(1, 2, 3, 4, 5)

	filtered := seq.Where(input, func(v int) bool {
		return v%2 == 0
	})

	result := seq.Collect(filtered)

	fmt.Printf("%v\n", result)
}
Output:

[2 4]

func Zip

func Zip[E any, R any](seq1 iter.Seq[E], seq2 iter.Seq[R]) iter.Seq2[E, R]

Zip combines two sequences into a iter.Seq2.

Example
package main

import (
	"fmt"

	"github.com/go-softwarelab/common/pkg/seq"
)

func main() {
	seq1 := seq.Of(1, 2, 3)
	seq2 := seq.Of("a", "b", "c")

	zipped := seq.Zip(seq1, seq2)

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

1: a
2: b
3: c

Types

type Consumer

type Consumer[E any] = func(E)

Consumer is a function that consumes an element of a sequence.

type Mapper

type Mapper[T any, R any] = func(T) R

Mapper is a function that maps a value of type T to a value of type R.

type Predicate

type Predicate[E any] = Mapper[E, bool]

Predicate is a function that takes an element and returns a boolean.

Jump to

Keyboard shortcuts

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