seq
import "github.com/go-softwarelab/common/pkg/seq"
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.
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]
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]
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]
Concat
func Concat[E any](sequences ...iter.Seq[E]) iter.Seq[E]
Concat concatenates multiple sequences into a single sequence.
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)
result := seq.Collect(concatenated)
fmt.Println(result)
}
Output
[1 2 3 4 5 6]
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
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
Count
func Count[E any](seq iter.Seq[E]) int
Count returns the number of elements in the sequence.
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]
CycleTimes
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]
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]
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
Empty
func Empty[E any]() iter.Seq[E]
Empty creates a new empty sequence.
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
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
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]
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
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]
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
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]
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]
FlattenSlices
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]
Flush
func Flush[E any](seq iter.Seq[E])
Flush consumes all elements of the input sequence.
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
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
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
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]
FromSliceReversed
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]
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]
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
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
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]
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]
MapOrErr
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
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
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
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
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
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]
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]
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]
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]
PointersFromSlice
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]
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]
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]
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]
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]
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
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
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]
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]
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]
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]
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.
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.
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]
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)
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)
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]
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.
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]
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
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
}
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]
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]
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]
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]
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]
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]
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
type Consumer
Consumer is a function that consumes an element of a sequence.
type Consumer[E any] = func(E)
type Mapper
Mapper is a function that maps a value of type T to a value of type R.
type Mapper[T any, R any] = func(T) R
type Predicate
Predicate is a function that takes an element and returns a boolean.
type Predicate[E any] = Mapper[E, bool]