Documentation
¶
Overview ¶
Package iter provides lazy, context-aware sequence transformations for Go 1.23 iter.Seq values.
The iter package is useful when you want to build allocation-light data pipelines over slices, files, database rows, or generated streams without materializing every intermediate result. Each helper returns a new lazy sequence or consumes one directly, so work only happens when the caller ranges over the final sequence.
Example:
ctx := context.Background()
numbers := slices.Values([]int{1, 2, 3, 4, 5})
for v := range iter.Filter(ctx, numbers, func(n int) bool {
return n%2 == 0
}) {
fmt.Println(v)
}
Any important notes about behaviour such as laziness, context cancellation, memory usage. Most functions are lazy and stop as soon as the context is cancelled or the consumer breaks early. Reverse buffers the full sequence in memory before yielding results, while helpers like Filter, Map, and Take stream values one at a time.
Index ¶
- func Chunk[T any](ctx context.Context, seq iter.Seq[T], n int) iter.Seq[[]T]
- func Contains[T comparable](ctx context.Context, seq iter.Seq[T], target T) bool
- func Distinct[T comparable](ctx context.Context, seq iter.Seq[T]) iter.Seq[T]
- func Filter[T any](ctx context.Context, seq iter.Seq[T], fn func(T) bool) iter.Seq[T]
- func FlatMap[T, U any](ctx context.Context, seq iter.Seq[T], fn func(T) iter.Seq[U]) iter.Seq[U]
- func Flatten[T any](ctx context.Context, seq iter.Seq[[]T]) iter.Seq[T]
- func ForEach[T any](ctx context.Context, seq iter.Seq[T], fn func(T))
- func Map[T, U any](ctx context.Context, seq iter.Seq[T], fn func(T) U) iter.Seq[U]
- func Reverse[T any](ctx context.Context, seq iter.Seq[T]) iter.Seq[T]
- func Take[T any](ctx context.Context, seq iter.Seq[T], n int) iter.Seq[T]
- func TakeWhile[T any](ctx context.Context, seq iter.Seq[T], fn func(T) bool) iter.Seq[T]
- func Validate[T any](ctx context.Context, seq iter.Seq[T], fn func(T) (bool, string), ...) iter.Seq[T]
- func Zip[A, B any](ctx context.Context, a iter.Seq[A], b iter.Seq[B]) iter.Seq[[2]any]
- type ValidateConfig
- type ValidationError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Chunk ¶
Chunk splits a sequence into slices of size n.
Example ¶
package main
import (
"context"
"fmt"
"slices"
viter "github.com/MostafaMagdSalama/vortex/iter"
)
func main() {
numbers := slices.Values([]int{1, 2, 3, 4, 5})
for batch := range viter.Chunk(context.Background(), numbers, 2) {
fmt.Println(batch)
}
}
Output: [1 2] [3 4] [5]
func Contains ¶
Contains returns true if the sequence contains the target value.
Example ¶
package main
import (
"context"
"fmt"
"slices"
viter "github.com/MostafaMagdSalama/vortex/iter"
)
func main() {
numbers := slices.Values([]int{1, 2, 3, 4, 5})
fmt.Println(viter.Contains(context.Background(), numbers, 3))
}
Output: true
func Distinct ¶
Distinct filters out duplicate values keeping only the first occurrence.
Example ¶
package main
import (
"context"
"fmt"
"slices"
viter "github.com/MostafaMagdSalama/vortex/iter"
)
func main() {
numbers := slices.Values([]int{1, 2, 1, 3, 2, 4})
for v := range viter.Distinct(context.Background(), numbers) {
fmt.Println(v)
}
}
Output: 1 2 3 4
func Filter ¶
Filter returns a new sequence containing only elements where fn returns true.
Example ¶
package main
import (
"context"
"fmt"
"slices"
viter "github.com/MostafaMagdSalama/vortex/iter"
)
func main() {
numbers := slices.Values([]int{1, 2, 3, 4, 5})
for v := range viter.Filter(context.Background(), numbers, func(n int) bool {
return n > 2
}) {
fmt.Println(v)
}
}
Output: 3 4 5
func FlatMap ¶
FlatMap transforms each element into a sequence, then flattens all sequences.
Example ¶
package main
import (
"context"
"fmt"
"iter"
"slices"
viter "github.com/MostafaMagdSalama/vortex/iter"
)
func main() {
numbers := slices.Values([]int{1, 2, 3})
for v := range viter.FlatMap(context.Background(), numbers, func(n int) iter.Seq[int] {
return slices.Values([]int{n, n * 10})
}) {
fmt.Println(v)
}
}
Output: 1 10 2 20 3 30
func Flatten ¶
Flatten converts a sequence of slices into a flat sequence of elements.
Example ¶
package main
import (
"context"
"fmt"
"slices"
viter "github.com/MostafaMagdSalama/vortex/iter"
)
func main() {
groups := slices.Values([][]int{{1, 2}, {3}, {4, 5}})
for v := range viter.Flatten(context.Background(), groups) {
fmt.Println(v)
}
}
Output: 1 2 3 4 5
func ForEach ¶
ForEach calls fn for every element in the sequence.
Example ¶
package main
import (
"context"
"fmt"
"slices"
viter "github.com/MostafaMagdSalama/vortex/iter"
)
func main() {
numbers := slices.Values([]int{1, 2, 3})
viter.ForEach(context.Background(), numbers, func(v int) {
fmt.Println(v * 2)
})
}
Output: 2 4 6
func Map ¶
Map transforms each element using fn.
Example ¶
package main
import (
"context"
"fmt"
"slices"
viter "github.com/MostafaMagdSalama/vortex/iter"
)
func main() {
numbers := slices.Values([]int{1, 2, 3})
for v := range viter.Map(context.Background(), numbers, func(n int) int {
return n * 10
}) {
fmt.Println(v)
}
}
Output: 10 20 30
func Reverse ¶
Reverse collects the sequence into memory and yields it in reverse order.
Example ¶
package main
import (
"context"
"fmt"
"slices"
viter "github.com/MostafaMagdSalama/vortex/iter"
)
func main() {
numbers := slices.Values([]int{1, 2, 3, 4, 5})
for v := range viter.Reverse(context.Background(), numbers) {
fmt.Println(v)
}
}
Output: 5 4 3 2 1
func Take ¶
Take returns the first n elements.
Example ¶
package main
import (
"context"
"fmt"
"slices"
viter "github.com/MostafaMagdSalama/vortex/iter"
)
func main() {
numbers := slices.Values([]int{1, 2, 3, 4, 5})
for v := range viter.Take(context.Background(), numbers, 3) {
fmt.Println(v)
}
}
Output: 1 2 3
func TakeWhile ¶
Example ¶
package main
import (
"context"
"fmt"
"slices"
viter "github.com/MostafaMagdSalama/vortex/iter"
)
func main() {
numbers := slices.Values([]int{1, 2, 3, 0, 4})
for v := range viter.TakeWhile(context.Background(), numbers, func(n int) bool {
return n > 0
}) {
fmt.Println(v)
}
}
Output: 1 2 3
func Validate ¶
func Validate[T any](ctx context.Context, seq iter.Seq[T], fn func(T) (bool, string), onError func(ValidationError[T])) iter.Seq[T]
Example ¶
package main
import (
"context"
"fmt"
"slices"
"github.com/MostafaMagdSalama/vortex/iter"
)
type User struct {
ID string
Name string
Email string
Status string
}
func validateUser(u User) (bool, string) {
if u.ID == "" {
return false, "missing ID"
}
if u.Name == "" {
return false, "missing name"
}
if u.Email == "" {
return false, "missing email"
}
if u.Status != "active" && u.Status != "inactive" {
return false, fmt.Sprintf("invalid status: %s", u.Status)
}
return true, ""
}
func main() {
users := slices.Values([]User{
{ID: "1", Name: "Alice", Email: "alice@example.com", Status: "active"},
{ID: "", Name: "Bob", Email: "bob@example.com", Status: "inactive"},
{ID: "3", Name: "Carol", Email: "carol@example.com", Status: "active"},
})
for user := range iter.Validate(context.Background(), users, validateUser, func(ve iter.ValidationError[User]) {
fmt.Println("invalid:", ve.Reason)
}) {
fmt.Println("valid:", user.Name)
}
}
Output: valid: Alice invalid: missing ID valid: Carol
func Zip ¶
Example ¶
package main
import (
"context"
"fmt"
"slices"
viter "github.com/MostafaMagdSalama/vortex/iter"
)
func main() {
left := slices.Values([]int{1, 2, 3})
right := slices.Values([]string{"a", "b", "c"})
for pair := range viter.Zip(context.Background(), left, right) {
fmt.Println(pair[0], pair[1])
}
}
Output: 1 a 2 b 3 c
Types ¶
type ValidateConfig ¶
type ValidateConfig[T any] struct { OnError func(ValidationError[T]) }
ValidateConfig controls what happens with invalid items.