iters

package
v0.0.0-...-89aa834 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2024 License: MIT Imports: 5 Imported by: 0

README

Go 1.23 Iterators: A Deep Dive

Introduction

Go 1.23 introduces a game-changing feature to the language: built-in support for iterators. This addition brings a more functional and flexible approach to working with sequences of data, aligning Go with modern programming paradigms while maintaining its trademark simplicity and efficiency. In this comprehensive guide, we'll explore the new iter package, diving deep into its core concepts, practical applications, and some of the more advanced functions it offers.

Understanding Iterators in Go 1.23

At its core, an iterator in Go 1.23 is a function that yields successive elements of a sequence to a callback function. The iter package defines two main types of iterators:

  1. Seq[V any]: For sequences of single values
  2. Seq2[K, V any]: For sequences of key-value pairs

These iterators are defined as function types:

type Seq[V any] func(yield func(V) bool)
type Seq2[K, V any] func(yield func(K, V) bool)

The yield function is called for each element in the sequence. It returns a boolean indicating whether the iteration should continue (true) or stop (false).

Basic Usage

Let's start with a simple example to illustrate how to use these iterators:

func PrintAll[V any](seq iter.Seq[V]) {
    for v := range seq {
        fmt.Println(v)
    }
}

This function takes a Seq[V] and prints all its elements. The range keyword is overloaded in Go 1.23 to work with iterators, making their usage intuitive and familiar.

Creating Iterators

The github.com/gopherd/core/container/iters package provides several utility functions to create and manipulate iterators. Let's look at some of them:

Enumerate

The Enumerate function creates an iterator from a slice:

func Enumerate[S ~[]E, E any](s S) iter.Seq[E] {
    return func(yield func(E) bool) {
        for _, v := range s {
            if !yield(v) {
                return
            }
        }
    }
}

Usage:

for v := range iters.Enumerate([]string{"a", "b", "c"}) {
    fmt.Println(v) // Output: a \n b \n c
}
Range

The Range function generates a sequence of numbers:

func Range[T cmp.Ordered](start, end, step T) iter.Seq[T] {
    // ... (error checking omitted for brevity)
    return func(yield func(T) bool) {
        if start < end {
            for i := start; i < end; i += step {
                if !yield(i) {
                    return
                }
            }
        } else {
            for i := start; i > end; i += step {
                if !yield(i) {
                    return
                }
            }
        }
    }
}

Usage:

for v := range iters.Range(1, 10, 2) {
    fmt.Println(v) // Output: 1 3 5 7 9
}

Advanced Iterator Functions

Now, let's dive into some of the more complex functions provided by the iters package.

Zip

The Zip function combines two sequences into a single sequence of pairs:

func Zip[T any, U any](s1 iter.Seq[T], s2 iter.Seq[U]) iter.Seq2[T, U] {
    return func(yield func(T, U) bool) {
        next, stop := iter.Pull(s2)
        defer stop()
        for v1 := range s1 {
            v2, _ := next()
            if !yield(v1, v2) {
                return
            }
        }
        var zero1 T
        for {
            if v2, ok := next(); !ok {
                return
            } else if !yield(zero1, v2) {
                return
            }
        }
    }
}

This function is particularly interesting because it demonstrates how to work with two iterators simultaneously. It uses the Pull function to convert s2 into a pull-style iterator, allowing for more control over the iteration process.

The Zip function continues until both input sequences are exhausted. If one sequence is longer than the other, the remaining elements are paired with zero values of the other type.

Usage:

seq1 := iters.Enumerate([]int{1, 2, 3})
seq2 := iters.Enumerate([]string{"a", "b", "c", "d"})
for v1, v2 := range iters.Zip(seq1, seq2) {
    fmt.Printf("(%d, %s)\n", v1, v2)
}
// Output:
// (1, a)
// (2, b)
// (3, c)
// (0, d)
Split

The Split function divides a slice into multiple chunks:

func Split[S ~[]T, T any](s S, n int) iter.Seq[[]T] {
    if n < 1 {
        panic("n must be positive")
    }
    return func(yield func([]T) bool) {
        total := len(s)
        size := total / n
        remainder := total % n
        i := 0
        for i < total {
            var chunk []T
            if remainder > 0 {
                chunk = s[i : i+size+1]
                remainder--
                i += size + 1
            } else {
                chunk = s[i : i+size]
                i += size
            }
            if !yield(chunk) {
                return
            }
        }
    }
}

This function is useful when you need to process a large slice in smaller, more manageable pieces. It ensures that the chunks are as evenly sized as possible, distributing any remainder elements among the first few chunks.

Usage:

data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
for chunk := range iters.Split(data, 3) {
    fmt.Println(chunk)
}
// Output:
// [1 2 3 4]
// [5 6 7]
// [8 9 10]
GroupBy

The GroupBy function is a powerful tool for organizing data based on a key function:

func GroupBy[K comparable, V any](s iter.Seq[V], f func(V) K) iter.Seq2[K, []V] {
    return func(yield func(K, []V) bool) {
        groups := make(map[K][]V)
        for v := range s {
            k := f(v)
            groups[k] = append(groups[k], v)
        }
        for k, vs := range groups {
            if !yield(k, vs) {
                return
            }
        }
    }
}

This function takes a sequence and a key function. It groups the elements of the sequence based on the keys produced by the key function. The result is a sequence of key-value pairs, where each key is associated with a slice of all elements that produced that key.

Usage:

data := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
evenOdd := func(n int) string {
    if n%2 == 0 {
        return "even"
    }
    return "odd"
}
for key, group := range iters.GroupBy(iters.Enumerate(data), evenOdd) {
    fmt.Printf("%s: %v\n", key, group)
}
// Output:
// odd: [1 3 5 7 9]
// even: [2 4 6 8 10]

The Power of Pull

The iter package introduces a powerful concept called "Pull", which converts a push-style iterator into a pull-style iterator. This is particularly useful when you need more control over the iteration process.

func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func())

The Pull function returns two functions:

  1. next: Returns the next value in the sequence and a boolean indicating if the value is valid.
  2. stop: Ends the iteration.

This allows for more complex iteration patterns, as demonstrated in the Zip function we saw earlier.

Conclusion

Go 1.23's introduction of iterators marks a significant evolution in the language's capabilities for handling sequences of data. The iter package provides a rich set of tools for creating, manipulating, and consuming iterators, enabling more expressive and functional programming styles while maintaining Go's simplicity and performance.

From basic operations like Enumerate and Range, to more complex functions like Zip, Split, and GroupBy, the new iterator system offers powerful abstractions for working with data sequences. The introduction of pull-style iterators through the Pull function further extends the flexibility and control available to developers.

As you incorporate these new features into your Go programs, you'll likely find new, more elegant solutions to common programming problems. The iterator system in Go 1.23 opens up exciting possibilities for data processing, functional programming, and beyond.

Remember, while iterators provide powerful abstractions, they should be used judiciously. In many cases, simple loops or slices may still be the most readable and performant solution. As with all features, the key is to understand the tools available and choose the right one for each specific task.

Happy iterating!

Documentation

Overview

Package iters provides utility functions for working with iterators and sequences.

Package iters provides utility functions for working with iterators and sequences.

Package iters provides utility functions for working with iterators and sequences.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Accumulate

func Accumulate[T constraints.Number | string](s iter.Seq[T], initial T) T

Accumulate returns the result of adding all elements in the sequence s to the initial value.

func AccumulateFunc

func AccumulateFunc[T, U any](s iter.Seq[T], f func(U, T) U, initial U) U

AccumulateFunc applies the function f to each element in the sequence s, accumulating the result starting from the initial value.

func AccumulateKeys

func AccumulateKeys[K constraints.Number | string, V any](m iter.Seq2[K, V], initial K) K

AccumulateKeys returns the result of adding all keys in the key-value sequence m to the initial value.

func AccumulateKeysFunc

func AccumulateKeysFunc[K, V, U any](m iter.Seq2[K, V], f func(U, K) U, initial U) U

AccumulateKeysFunc applies the function f to each key in the key-value sequence m, accumulating the result starting from the initial value.

func AccumulateValues

func AccumulateValues[K any, V constraints.Number | string](m iter.Seq2[K, V], initial V) V

AccumulateValues returns the result of adding all values in the key-value sequence m to the initial value.

func AccumulateValuesFunc

func AccumulateValuesFunc[K, V, U any](m iter.Seq2[K, V], f func(U, V) U, initial U) U

AccumulateValuesFunc applies the function f to each value in the key-value sequence m, accumulating the result starting from the initial value.

func AppendSeq2

func AppendSeq2[S ~[]pair.Pair[K, V], K, V any](s S, m iter.Seq2[K, V]) S

AppendSeq2 appends the key-value pairs from seq to the slice and returns the extended slice.

func Collect2

func Collect2[K, V any](m iter.Seq2[K, V]) []pair.Pair[K, V]

Collect2 collects key-value pairs from seq into a new slice and returns it.

func Concat

func Concat[T any](ss ...iter.Seq[T]) iter.Seq[T]

Concat returns an iterator that generates a sequence of elements from all input sequences.

func Concat2

func Concat2[K, V any](ms ...iter.Seq2[K, V]) iter.Seq2[K, V]

Concat2 returns an iterator that generates a sequence of key-value pairs from all input sequences.

func Contains

func Contains[T comparable](s iter.Seq[T], target T) bool

Contains returns true if the sequence s contains the target element.

func ContainsFunc

func ContainsFunc[T any](s iter.Seq[T], f func(T) bool) bool

ContainsFunc returns true if the sequence s contains an element for which the function f returns true.

func Count

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

Count returns the number of elements in the sequence s.

func CountFunc

func CountFunc[T any](s iter.Seq[T], f func(T) bool) int

CountFunc returns the number of elements in the sequence s for which the function f returns true.

func Distinct

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

Distinct returns an iterator that generates a sequence of distinct elements from s.

func DistinctFunc

func DistinctFunc[F ~func(T) K, T any, K comparable](s iter.Seq[T], f F) iter.Seq[K]

DistinctFunc returns an iterator that generates a sequence of distinct elements from s.

func Enumerate

func Enumerate[S ~[]E, E any](s S) iter.Seq[E]

Enumerate returns an iterator that generates a sequence of values for each element in the slice. The index of the element is not provided. If you need the index, use slices.All instead.

Example:

for v := range Enumerate([]string{"a", "b", "c"}) {
	fmt.Println(v) // Output: a \n b \n c
}
Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	fruits := []string{"apple", "banana", "cherry"}
	for v := range iters.Enumerate(fruits) {
		fmt.Println(v)
	}
}
Output:

apple
banana
cherry

func Filter

func Filter[T any](s iter.Seq[T], f func(T) bool) iter.Seq[T]

Filter returns an iterator that generates a sequence of elements from s for which the function f returns true.

Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	s := iters.List(1, 2, 3, 4, 5, 6)
	evenNumbers := iters.Filter(s, func(i int) bool { return i%2 == 0 })
	for v := range evenNumbers {
		fmt.Printf("%d ", v)
	}
}
Output:

2 4 6

func Filter2

func Filter2[K, V any](m iter.Seq2[K, V], f func(K, V) bool) iter.Seq2[K, V]

Filter2 returns an iterator that generates a sequence of key-value pairs from m for which the function f returns true.

func GroupBy

func GroupBy[K comparable, V any](s iter.Seq[V], f func(V) K) iter.Seq2[K, []V]

GroupBy returns an iterator that generates a sequence of key-value pairs, where the key is the result of applying the function f to each element in s, and the value is a slice of all elements in s that produced that key.

Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	s := iters.List(1, 2, 3, 4, 5, 6)
	groups := iters.GroupBy(s, func(i int) string {
		if i%2 == 0 {
			return "even"
		}
		return "odd"
	})
	for k, v := range groups {
		fmt.Printf("%s: %v\n", k, v)
	}
}
Output:

even: [2 4 6]
odd: [1 3 5]

func Infinite

func Infinite() iter.Seq[int]

Infinite returns an iterator that generates an infinite sequence of integers starting from 0.

func Keys

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

Keys returns an iterator that generates a sequence of keys from the key-value sequence m.

Example
package main

import (
	"fmt"
	"maps"
	"sort"

	"github.com/gopherd/core/container/iters"
)

func main() {
	m := map[string]int{"a": 1, "b": 2, "c": 3}
	result := make([]string, 0, 3)
	for k := range iters.Keys(maps.All(m)) {
		result = append(result, k)
	}

	// Sort the result for consistent output
	sort.Strings(result)
	fmt.Println(result)
}
Output:

[a b c]

func LessThan

func LessThan[T constraints.Real](end T) iter.Seq[T]

LessThan returns an iterator that generates a sequence of numbers [0, end) with a step size of 1. It panics if end is negative.

Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	for v := range iters.LessThan(3) {
		fmt.Print(v, " ")
	}
}
Output:

0 1 2

func List

func List[T any](values ...T) iter.Seq[T]

List returns an iterator that generates a sequence of the provided values.

func Map

func Map[T, U any](s iter.Seq[T], f func(T) U) iter.Seq[U]

Map returns an iterator that applies the function f to each element in s.

func Map2

func Map2[K, V, U any](m iter.Seq2[K, V], f func(K, V) U) iter.Seq[U]

Map2 returns an iterator that applies the function f to each key-value pair in m.

func Max

func Max[T cmp.Ordered](s iter.Seq[T]) T

Max returns the maximum element in the sequence s. It panics if s is empty.

Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	max := iters.Max(iters.List(3, 1, 4, 1, 5, 9))
	fmt.Println(max)
}
Output:

9

func Max2

func Max2[K, V cmp.Ordered](s iter.Seq2[K, V]) (K, V)

Max2 returns the maximum key-value pair in the key-value sequence m.

func MaxFunc

func MaxFunc[T any](s iter.Seq[T], f func(T, T) int) T

MaxFunc returns the element in the sequence s for which the function f returns the maximum value.

func MaxFunc2

func MaxFunc2[K, V any](s iter.Seq2[K, V], f func(pair.Pair[K, V], pair.Pair[K, V]) int) (K, V)

MaxFunc2 returns the key-value pair in the key-value sequence m for which the function f returns the maximum value.

func MaxKey

func MaxKey[K cmp.Ordered, V any](m iter.Seq2[K, V]) K

MaxKey returns the maximum key in the key-value sequence m.

Example
package main

import (
	"fmt"
	"maps"

	"github.com/gopherd/core/container/iters"
)

func main() {
	data := map[int]string{3: "three", 1: "one", 4: "four", 5: "five"}
	maxKey := iters.MaxKey(maps.All(data))
	fmt.Println(maxKey)
}
Output:

5

func MaxValue

func MaxValue[K any, V cmp.Ordered](m iter.Seq2[K, V]) V

MaxValue returns the maximum value in the key-value sequence m.

Example
package main

import (
	"fmt"
	"maps"

	"github.com/gopherd/core/container/iters"
)

func main() {
	data := map[string]int{"three": 3, "one": 1, "four": 4, "five": 5}
	maxValue := iters.MaxValue(maps.All(data))
	fmt.Println(maxValue)
}
Output:

5

func Min

func Min[T cmp.Ordered](s iter.Seq[T]) T

Min returns the minimum element in the sequence s. It panics if s is empty.

Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	min := iters.Min(iters.List(3, 1, 4, 1, 5, 9))
	fmt.Println(min)
}
Output:

1

func Min2

func Min2[K, V cmp.Ordered](s iter.Seq2[K, V]) (K, V)

Min2 returns the minimum key-value pair in the key-value sequence m.

func MinFunc

func MinFunc[T any](s iter.Seq[T], f func(T, T) int) T

MinFunc returns the element in the sequence s for which the function f returns the minimum value.

func MinFunc2

func MinFunc2[K, V any](s iter.Seq2[K, V], f func(pair.Pair[K, V], pair.Pair[K, V]) int) (K, V)

MinFunc2 returns the key-value pair in the key-value sequence m for which the function f returns the minimum value.

func MinKey

func MinKey[K cmp.Ordered, V any](m iter.Seq2[K, V]) K

MinKey returns the minimum key in the key-value sequence m.

Example
package main

import (
	"fmt"
	"maps"

	"github.com/gopherd/core/container/iters"
)

func main() {
	data := map[int]string{3: "three", 1: "one", 4: "four", 5: "five"}
	minKey := iters.MinKey(maps.All(data))
	fmt.Println(minKey)
}
Output:

1

func MinMax

func MinMax[T cmp.Ordered](s iter.Seq[T]) (min, max T)

MinMax returns the minimum and maximum elements in the sequence s. It panics if s is empty.

Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	min, max := iters.MinMax(iters.List(3, 1, 4, 1, 5, 9))
	fmt.Printf("Min: %d, Max: %d\n", min, max)
}
Output:

Min: 1, Max: 9

func MinMax2

func MinMax2[K, V cmp.Ordered](s iter.Seq2[K, V]) (min, max pair.Pair[K, V])

MinMax2 returns the key-value pairs with the minimum and maximum values in the key-value sequence m.

func MinMaxFunc

func MinMaxFunc[T any](s iter.Seq[T], f func(T, T) int) (min, max T)

MinMaxFunc returns the elements in the sequence s for which the function f returns the minimum and maximum values.

func MinMaxFunc2

func MinMaxFunc2[K, V any](s iter.Seq2[K, V], f func(pair.Pair[K, V], pair.Pair[K, V]) int) (min, max pair.Pair[K, V])

MinMaxFunc2 returns the key-value pairs with the minimum and maximum values in the key-value sequence m.

func MinMaxKey

func MinMaxKey[K cmp.Ordered, V any](m iter.Seq2[K, V]) (min, max K)

MinMaxKey returns the minimum and maximum keys in the key-value sequence m.

func MinMaxValue

func MinMaxValue[K any, V cmp.Ordered](m iter.Seq2[K, V]) (min, max V)

MinMaxValue returns the key-value pairs with the minimum and maximum values in the key-value sequence m.

func MinValue

func MinValue[K any, V cmp.Ordered](m iter.Seq2[K, V]) V

MinValue returns the minimum value in the key-value sequence m.

Example
package main

import (
	"fmt"
	"maps"

	"github.com/gopherd/core/container/iters"
)

func main() {
	data := map[string]int{"three": 3, "one": 1, "four": 4, "five": 5}
	minValue := iters.MinValue(maps.All(data))
	fmt.Println(minValue)
}
Output:

1

func Range

func Range[T cmp.Ordered](start, end, step T) iter.Seq[T]

Range returns an iterator that generates a sequence of numbers from start to end with a step size of step. The sequence includes start but excludes end.

It panics if step is zero, or if start < end and step is negative, or if start > end and step is positive.

Example:

for v := range Range(1, 10, 2) {
	fmt.Println(v) // Output: 1 3 5 7 9
}
Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	for v := range iters.Range(1, 10, 2) {
		fmt.Print(v, " ")
	}
}
Output:

1 3 5 7 9

func Repeat

func Repeat[T any](v T, n int) iter.Seq[T]

Repeat returns an iterator that generates a sequence of n elements, each with the value v. It panics if n is negative.

Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	for v := range iters.Repeat("Go", 3) {
		fmt.Print(v, " ")
	}
}
Output:

Go Go Go

func Sort

func Sort[T cmp.Ordered](s iter.Seq[T]) iter.Seq[T]

Sort returns an iterator that generates a sorted sequence of the elements in s.

func Sort2

func Sort2[K, V cmp.Ordered](m iter.Seq2[K, V]) iter.Seq2[K, V]

Sort2 returns an iterator that generates a sorted sequence of the key-value pairs in m.

func SortFunc

func SortFunc[T any](s iter.Seq[T], cmp func(T, T) int) iter.Seq[T]

SortFunc returns an iterator that generates a sorted sequence of the elements in s using the comparison function.

func SortFunc2

func SortFunc2[K, V any](m iter.Seq2[K, V], cmp func(pair.Pair[K, V], pair.Pair[K, V]) int) iter.Seq2[K, V]

SortFunc2 returns an iterator that generates a sorted sequence of the key-value pairs in m using the comparison function.

func SortKeys

func SortKeys[K cmp.Ordered, V any](m iter.Seq2[K, V]) iter.Seq2[K, V]

SortKeys returns an iterator that generates a sorted sequence of the key-value pairs in m by key.

func SortValues

func SortValues[K any, V cmp.Ordered](m iter.Seq2[K, V]) iter.Seq2[K, V]

SortValues returns an iterator that generates a sorted sequence of the key-value pairs in m by value.

func Split

func Split[S ~[]T, T any](s S, n int) iter.Seq[[]T]

Split returns an iterator that generates a sequence of chunks from s. The sequence is split into n chunks of approximately equal size. It panics if n is less than 1.

Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	chunks := iters.Split(slice, 3)
	for chunk := range chunks {
		fmt.Println(chunk)
	}
}
Output:

[1 2 3 4]
[5 6 7]
[8 9 10]

func Steps

func Steps[T constraints.Number](n int, start T, steps ...T) iter.Seq[T]

Steps returns an iterator that generates a sequence of n numbers. The behavior of the sequence depends on the provided start value and optional steps.

Parameters:

  • n: The number of elements to generate in the sequence.
  • start: The starting value of the sequence.
  • steps: Optional variadic parameter defining the increments for the sequence.

If no steps are provided, it generates a sequence starting from 'start' and incrementing by 1 each time. If steps are provided, it generates a sequence starting from 'start', then repeatedly applying the steps in a cyclic manner to generate subsequent values.

It panics if n is negative.

Examples:

// No steps provided (increment by 1):
for v := range Steps(5, 10) {
    fmt.Print(v, " ") // Output: 10 11 12 13 14
}

// Single step provided:
for v := range Steps(5, 1, 2) {
    fmt.Print(v, " ") // Output: 1 3 5 7 9
}

// Multiple steps provided:
for v := range Steps(6, 1, 2, 3, 4) {
    fmt.Print(v, " ") // Output: 1 3 6 10 12 15
}

// Using negative steps:
for v := range Steps(5, 20, -1, -2, -3) {
    fmt.Print(v, " ") // Output: 20 19 17 14 13
}
Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	for v := range iters.Steps(5, 1, 2, 3) {
		fmt.Print(v, " ")
	}
}
Output:

1 3 6 8 11

func Sum

func Sum[T constraints.Number | string](s iter.Seq[T]) T

Sum returns the sum of all elements in the sequence s.

func SumKeys

func SumKeys[K constraints.Number | string, V any](m iter.Seq2[K, V]) K

SumKeys returns the sum of all keys in the key-value sequence m.

func SumValues

func SumValues[K any, V constraints.Number | string](m iter.Seq2[K, V]) V

SumValues returns the sum of all values in the key-value sequence m.

func Unique

func Unique[T comparable](s iter.Seq[T]) iter.Seq[T]

Unique returns an iterator that generates a sequence of unique elements from s. Adjacent duplicate elements are removed. The sequence must be sorted. If not, use the Sort function first or the Distinct function directly.

Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	s := iters.List(1, 2, 2, 3, 3, 3, 4)
	for v := range iters.Unique(s) {
		fmt.Printf("%d ", v)
	}
}
Output:

1 2 3 4

func UniqueFunc

func UniqueFunc[F ~func(T, T) bool, T comparable](s iter.Seq[T], eq F) iter.Seq[T]

UniqueFunc returns an iterator that generates a sequence of unique elements from s. Adjacent elements are considered duplicates if the function f returns the same value for them. The sequence must be sorted. If not, use the SortFunc first or the DistinctFunc directly.

Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	numbers := []int{1, 1, 2, 3, 3, 4, 4, 4, 5}
	eq := func(a, b int) bool { return a == b }

	uniqueSeq := iters.UniqueFunc(iters.List(numbers...), eq)
	for v := range uniqueSeq {
		fmt.Print(v, " ")
	}
}
Output:

1 2 3 4 5

func Values

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

Values returns an iterator that generates a sequence of values from the key-value sequence m.

Example
package main

import (
	"fmt"
	"maps"
	"sort"

	"github.com/gopherd/core/container/iters"
)

func main() {
	m := map[string]int{"a": 1, "b": 2, "c": 3}
	result := make([]int, 0, 3)
	for v := range iters.Values(maps.All(m)) {
		result = append(result, v)
	}

	// Sort the result for consistent output
	sort.Ints(result)
	fmt.Println(result)
}
Output:

[1 2 3]

func WithIndex

func WithIndex[T any](s iter.Seq[T]) iter.Seq2[int, T]

WithIndex returns an iterator that generates a sequence of index-value pairs from s.

func Zip

func Zip[T any, U any](s1 iter.Seq[T], s2 iter.Seq[U]) iter.Seq2[T, U]

Zip returns an iterator that generates pairs of elements from s1 and s2. If one sequence is longer, remaining elements are paired with zero values.

Example
package main

import (
	"fmt"

	"github.com/gopherd/core/container/iters"
)

func main() {
	s1 := iters.List(1, 2, 3)
	s2 := iters.List("a", "b", "c")
	for v1, v2 := range iters.Zip(s1, s2) {
		fmt.Printf("%d: %s\n", v1, v2)
	}
}
Output:

1: a
2: b
3: c

Types

This section is empty.

Jump to

Keyboard shortcuts

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