Skip to main content

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]