Documentation
¶
Overview ¶
Package iterate2 builds around iter.Seq2.
Index ¶
- Constants
- func Concatenate[First any, Second any](sequences ...iter.Seq2[First, Second]) iter.Seq2[First, Second]
- func Const[First any, Second any](first First, second Second) func(yield func(First, Second) bool)
- func Empty[First any, Second any](_ func(First, Second) bool)
- func Filter[First any, Second any](predicate func(First, Second) bool) func(iter.Seq2[First, Second]) iter.Seq2[First, Second]
- func ForEach[First any, Second any](invoke func(First, Second)) func(iter.Seq2[First, Second])
- func Map[FirstOutput any, SecondOutput any, Input any](convert func(Input) (FirstOutput, SecondOutput)) func(iter.Seq[Input]) iter.Seq2[FirstOutput, SecondOutput]
- func Map2[FirstOutput any, SecondOutput any, FirstInput any, SecondInput any](convert func(FirstInput, SecondInput) (FirstOutput, SecondOutput)) func(iter.Seq2[FirstInput, SecondInput]) iter.Seq2[FirstOutput, SecondOutput]
- func OverFunc[First any, Second any](f func() (First, Second)) iter.Seq2[First, Second]
- func Reduce[Result any, First any, Second any](initial Result, ...) func(iter.Seq2[First, Second]) Result
- func Repeat[First any, Second any](count int, reusable bool) func(iter.Seq2[First, Second]) iter.Seq2[First, Second]
- func Swap[First, Second any](sequence iter.Seq2[First, Second]) iter.Seq2[Second, First]
- func Until[First any, Second any](predicate func(First, Second) bool) func(iter.Seq2[First, Second]) iter.Seq2[First, Second]
- func While[First any, Second any](predicate func(First, Second) bool) func(iter.Seq2[First, Second]) iter.Seq2[First, Second]
- func Zip[First any, Second any](firstSequence iter.Seq[First], secondSequence iter.Seq[Second]) iter.Seq2[First, Second]
Examples ¶
Constants ¶
const ( Never = 0 InfiniteTimes = -1 )
Useful count constants to use with Repeat.
const ( IsReusable = true IsNotReusable = false )
Determine whether a sequence is reusable when calling Repeat.
Variables ¶
This section is empty.
Functions ¶
func Concatenate ¶
func Concatenate[First any, Second any](sequences ...iter.Seq2[First, Second]) iter.Seq2[First, Second]
Concatenate takes multiple sequences and concatenates them.
If any of the sequences is an infinite sequence, every sequence after that will never have taken values from.
Finite if all underlying iterators are finite, else infinite.
Reusable if all underlying iterators are reusable.
Example ¶
package main
import (
"fmt"
"slices"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
inputs := [][]string{
{"Peter", "Paul"},
{"Mary", "Joannah"},
}
for i, s := range iterate2.Concatenate(slices.All(inputs[0]), slices.All(inputs[1])) {
fmt.Printf("%d: %s\n", i, s)
}
}
Output: 0: Peter 1: Paul 0: Mary 1: Joannah
func Const ¶ added in v1.1.0
Const creates an iterator that returns the same value pair repeatedly.
Infinite iterator. Reusable.
Example ¶
package main
import (
"fmt"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
count := 0
for name, age := range iterate2.Const("Someone", 69) {
count++
if count > 3 {
break
}
fmt.Printf("%s is %d years old. Nice!\n", name, age)
}
}
Output: Someone is 69 years old. Nice! Someone is 69 years old. Nice! Someone is 69 years old. Nice!
func Empty ¶ added in v1.1.0
Empty is an iterator which yields no values at all.
Obviously finite and reusable.
func Filter ¶
func Filter[First any, Second any](predicate func(First, Second) bool) func(iter.Seq2[First, Second]) iter.Seq2[First, Second]
Filter yields values from a sequence for which a predicate holds true.
See the pred2 subpackage for pre-defined predicates.
Finiteness and reusability depend on the underlying sequence.
Example ¶
package main
import (
"fmt"
"slices"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
sumIsEven := func(first int, second int) bool {
return (first+second)%2 == 0
}
values := []int{1, 1, 2, 2, 3, 3}
for i, n := range iterate2.Filter(sumIsEven)(slices.All(values)) {
fmt.Printf("index %d + value %d = %d\n", i, n, i+n)
}
}
Output: index 1 + value 1 = 2 index 2 + value 2 = 4 index 5 + value 3 = 8
func ForEach ¶
ForEach invokes a function for every entry from a sequence.
Returns only after exhausting the iterator. Does not return for infinite iterators.
Example ¶
package main
import (
"fmt"
"maps"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
people := map[string]int{
"Peter": 18,
"Paul": 55,
"Mary": 32,
}
output := func(name string, age int) {
fmt.Printf("%s is %d years old.\n", name, age)
}
iterate2.ForEach(output)(maps.All(people))
}
Output: Peter is 18 years old. Paul is 55 years old. Mary is 32 years old.
func Map ¶
func Map[FirstOutput any, SecondOutput any, Input any](convert func(Input) (FirstOutput, SecondOutput)) func(iter.Seq[Input]) iter.Seq2[FirstOutput, SecondOutput]
Map maps values from an iter.Seq into other values, given a conversion function.
Finiteness and reusability depend on the underlying sequence.
Example ¶
package main
import (
"fmt"
"slices"
"strings"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
input := []string{"a", "baa", "aaaxxx"}
// convert cuts of "a"s from the front of s, returns whether any were found and the length of the remaining string.
convert := func(s string) (bool, int) {
ok := strings.HasPrefix(s, "a")
s = strings.TrimLeft(s, "a")
return ok, len(s)
}
for ok, n := range iterate2.Map(convert)(slices.Values(input)) {
if ok {
fmt.Printf("Some 'a's were removed, rest has length %d.\n", n)
} else {
fmt.Printf("No 'a's were removed, length is %d.\n", n)
}
}
}
Output: Some 'a's were removed, rest has length 0. No 'a's were removed, length is 3. Some 'a's were removed, rest has length 3.
func Map2 ¶
func Map2[FirstOutput any, SecondOutput any, FirstInput any, SecondInput any](convert func(FirstInput, SecondInput) (FirstOutput, SecondOutput)) func(iter.Seq2[FirstInput, SecondInput]) iter.Seq2[FirstOutput, SecondOutput]
Map maps values from an iter.Seq2 into other values, given a conversion function.
Finiteness and reusability depend on the underlying sequence.
Example ¶
package main
import (
"fmt"
"maps"
"strings"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
input := map[string]int{
"ab": 2,
"xyz": 1,
"foo": 3,
}
convert := func(s string, n int) (int, string) {
s = strings.Repeat(s, n)
return len(s), s
}
for n, s := range iterate2.Map2(convert)(maps.All(input)) {
fmt.Printf("'%s' has length %d.\n", s, n)
}
}
Output: 'abab' has length 4. 'xyz' has length 3. 'foofoofoo' has length 9.
func OverFunc ¶ added in v1.1.0
OverFunc creates an iterator that calls f for values.
Infinite iterator. Whether it is reusable or not depends on f.
Example ¶
package main
import (
"fmt"
"strconv"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
var current int = 0
counter := func() (int, string) {
current++
return current, strconv.Itoa(current)
}
for intValue, stringValue := range iterate2.OverFunc(counter) {
if intValue > 3 {
break
}
fmt.Println(intValue, stringValue)
}
}
Output: 1 1 2 2 3 3
func Reduce ¶
func Reduce[Result any, First any, Second any](initial Result, reducer func(current Result, first First, second Second) Result) func(iter.Seq2[First, Second]) Result
Reduce reduces values from a sequence into a single value.
Do not pass infinite iterators as this would lead to Reduce never returning.
Example ¶
package main
import (
"fmt"
"maps"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
f := func(current int, s string, subtract bool) int {
if subtract {
return current - len(s)
}
return current + len(s)
}
inputs := map[string]bool{
"foo": false,
"a": true,
"foobar": false,
"xyz": true,
}
fmt.Println(iterate2.Reduce(0, f)(maps.All(inputs)))
}
Output: 5
func Repeat ¶
func Repeat[First any, Second any](count int, reusable bool) func(iter.Seq2[First, Second]) iter.Seq2[First, Second]
Repeat repeats sequences.
count determines how often the sequence is to be repeated. A value of 0 creates a sequence with no values, a negative value repeats forever. Pass NoRepetition or InfiniteRepetitions for enhanced readability.
reusable determines whether the given iterator can be re-used. If not (and count is not 0), all values from the underlying iterator are stored. Warning: Can lead to unbounded memory usage in case of an infinite iterator.
Example (Infinite) ¶
package main
import (
"fmt"
"slices"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
count := 0
for _, s := range iterate2.Repeat[int, string](iterate2.InfiniteTimes, iterate2.IsReusable)(slices.All([]string{"xyz"})) {
fmt.Println(s)
count++
if count >= 3 {
break
}
}
}
Output: xyz xyz xyz
Example (NotReusable) ¶
package main
import (
"fmt"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
var exhausted bool
iterator := func(yield func(number int, name string) bool) {
if exhausted {
return
}
yield(1, "one")
yield(2, "two")
yield(3, "three")
exhausted = true
}
for n, s := range iterate2.Repeat[int, string](2, iterate2.IsNotReusable)(iterator) {
fmt.Printf("%d -> %s\n", n, s)
}
}
Output: 1 -> one 2 -> two 3 -> three 1 -> one 2 -> two 3 -> three
Example (Reusable) ¶
package main
import (
"fmt"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
iterator := func(yield func(name string, age int) bool) {
yield("Peter", 25)
yield("Paul", 17)
yield("Mary", 22)
}
for name, age := range iterate2.Repeat[string, int](2, iterate2.IsReusable)(iterator) {
fmt.Printf("%s is %d years old.\n", name, age)
}
}
Output: Peter is 25 years old. Paul is 17 years old. Mary is 22 years old. Peter is 25 years old. Paul is 17 years old. Mary is 22 years old.
func Swap ¶
Swap takes a iter.Seq2 and returns a new iter.Seq2 with first and second values swapped.
Example ¶
package main
import (
"fmt"
"maps"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
ages := map[string]int{
"Peter": 33,
"Paul": 22,
"Mary": 27,
}
for age, name := range iterate2.Swap(maps.All(ages)) {
fmt.Printf("%s is %d years old.\n", name, age)
}
}
Output: Peter is 33 years old. Paul is 22 years old. Mary is 27 years old.
func Until ¶ added in v1.2.0
func Until[First any, Second any](predicate func(First, Second) bool) func(iter.Seq2[First, Second]) iter.Seq2[First, Second]
Until yields values from a sequence until the given predicate becomes true.
See the pred2 subpackage for pre-defined predicates.
The resulting iterator is finite if the predicate ever becomes true.
Reusable if underlying sequence is reusable.
Example ¶
package main
import (
"errors"
"fmt"
"slices"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
results := slices.All(
[]error{
nil,
nil,
nil,
errors.New("broken"),
nil,
},
)
errorOccured := func(_ int, err error) bool {
return err != nil
}
for i := range iterate2.Until(errorOccured)(results) {
fmt.Println(i)
}
}
Output: 0 1 2
func While ¶
func While[First any, Second any](predicate func(First, Second) bool) func(iter.Seq2[First, Second]) iter.Seq2[First, Second]
While yields values from a sequence while a predicate holds true.
See the pred2 subpackage for pre-defined predicates.
Creates finite iterators from infinite iterators.
Reusable if underlying sequence is reusable.
Example ¶
package main
import (
"fmt"
"slices"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
sumIsLessThan := func(maximum int) func(first int, second int) bool {
return func(first int, second int) bool {
return first+second < maximum
}
}
values := []int{2, 3, 5, 7, 11, 13, 17, 19}
for i, n := range iterate2.While(sumIsLessThan(10))(slices.All(values)) {
fmt.Printf("index %d + value %d = %d\n", i, n, i+n)
}
}
Output: index 0 + value 2 = 2 index 1 + value 3 = 4 index 2 + value 5 = 7
func Zip ¶
func Zip[First any, Second any](firstSequence iter.Seq[First], secondSequence iter.Seq[Second]) iter.Seq2[First, Second]
Zip takes two single-value sequences and zips them into a two-value sequence. If any of the sequences ends, the resulting sequence ends as well. In the case that one sequence ends and the other doesn't, one value from the sequence that did not end is still taken.
If both first sequence and second sequence are infinite, Zip creates an infinite iterator, else it is finite.
Also both sequences need to be reusable for Zip to create a reusable iterator as well.
Example ¶
package main
import (
"fmt"
"slices"
"github.com/GodsBoss/g/seq/iterate2"
)
func main() {
givenNames := []string{"Peter", "Paul", "Mary"}
familyNames := []string{"Smith", "Miller", "Doe"}
zipped := iterate2.Zip(
slices.Values(givenNames),
slices.Values(familyNames),
)
for givenName, familyName := range zipped {
fmt.Printf("%s %s\n", givenName, familyName)
}
}
Output: Peter Smith Paul Miller Mary Doe
Types ¶
This section is empty.