pred2

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2025 License: GPL-3.0 Imports: 2 Imported by: 0

Documentation

Overview

Package pred2 contains predicates for iterate2's Filter() and While() iterators.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AllOf

func AllOf[First any, Second any](predicates ...func(First, Second) bool) func(First, Second) bool

AllOf creates a predicate that returns false if at least one of the given predicates returns false, else true.

Example
package main

import (
	"fmt"
	"maps"

	"github.com/GodsBoss/g/seq/iterate2"
	"github.com/GodsBoss/g/seq/iterate2/pred2"
)

func main() {
	sumIsEven := func(i, j int) bool {
		return (i+j)%2 == 0
	}

	firstIsGreater := func(i, j int) bool {
		return i > j
	}

	inputs := map[int]int{
		8: 4,
		4: 8,
		6: 3,
		3: 6,
	}

	for i, j := range iterate2.Filter(pred2.AllOf(sumIsEven, firstIsGreater))(maps.All(inputs)) {
		fmt.Printf("(%d, %d)\n", i, j)
	}

}
Output:
(8, 4)

func AnyOf

func AnyOf[First any, Second any](predicates ...func(First, Second) bool) func(First, Second) bool

AnyOf creates a predicate that returns true if at least one of the given predicates returns true, else false.

Example
package main

import (
	"fmt"
	"maps"

	"github.com/GodsBoss/g/seq/iterate2"
	"github.com/GodsBoss/g/seq/iterate2/pred2"
)

func main() {
	sumIsEven := func(i, j int) bool {
		return (i+j)%2 == 0
	}

	firstIsGreater := func(i, j int) bool {
		return i > j
	}

	inputs := map[int]int{
		4: 8,
		8: 4,
		6: 3,
		3: 6,
	}

	for i, j := range iterate2.Filter(pred2.AnyOf(sumIsEven, firstIsGreater))(maps.All(inputs)) {
		fmt.Printf("(%d, %d)\n", i, j)
	}

}
Output:
(4, 8)
(8, 4)
(6, 3)

func ContextIsValid

func ContextIsValid[First any, Second any](ctx context.Context) func(_ First, _ Second) bool

ContextIsValid creates a predicate that holds true until a context is canceled.

Example
package main

import (
	"context"
	"fmt"
	"slices"
	"time"

	"github.com/GodsBoss/g/seq/iterate2"
	"github.com/GodsBoss/g/seq/iterate2/pred2"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())

	// Cancel the context after 50 milliseconds. In practice a context would more likely be canceled
	// when a request times out or a server was signalled to be shutdown.
	go func() {
		time.Sleep(time.Millisecond * 50)
		cancel()
	}()

	items := []int{2, 3, 5, 7, 11, 13, 17, 19}

	for _, n := range iterate2.While(pred2.ContextIsValid[int, int](ctx))(slices.All(items)) {
		fmt.Println(n)
		time.Sleep(time.Millisecond * 15)
	}

}
Output:
2
3
5
7

func Not

func Not[First any, Second any](predicate func(First, Second) bool) func(First, Second) bool

Not inverts the given predicate.

Example
package main

import (
	"fmt"
	"maps"

	"github.com/GodsBoss/g/seq/iterate2"
	"github.com/GodsBoss/g/seq/iterate2/pred2"
)

func main() {
	stringLengthMatches := func(str string, length int) bool {
		return len(str) == length
	}

	inputs := map[string]int{
		"foo":    3,
		"bar":    4,
		"baz":    5,
		"foobar": 6,
	}

	for str, length := range iterate2.Filter(pred2.Not(stringLengthMatches))(maps.All(inputs)) {
		fmt.Printf("'%s' does not have length %d.\n", str, length)
	}

}
Output:
'bar' does not have length 4.
'baz' does not have length 5.

func PassFirstTo

func PassFirstTo[First any, Second any](predicate func(First) bool) func(first First, _ Second) bool

PassFirstTo takes a one-valued predicate and converts it into a two-valued predicate, passing the first argument.

Example
package main

import (
	"fmt"
	"maps"

	"github.com/GodsBoss/g/seq/iterate2"
	"github.com/GodsBoss/g/seq/iterate2/pred2"
)

func main() {
	strLengthAtLeast := func(minimum int) func(s string) bool {
		return func(s string) bool {
			return len(s) >= minimum
		}
	}

	values := map[string]string{
		"baz":    "baz",
		"foo":    "foobar",
		"barfoo": "bar",
		"foobar": "barfoo",
	}

	for k, v := range iterate2.Filter(pred2.PassFirstTo[string, string](strLengthAtLeast(5)))(maps.All(values)) {
		fmt.Printf("%s => %s\n", k, v)
	}

}
Output:
barfoo => bar
foobar => barfoo

func PassSecondTo

func PassSecondTo[First any, Second any](predicate func(Second) bool) func(_ First, second Second) bool

PassSecondTo takes a one-valued predicate and converts it into a two-valued predicate, passing the second argument.

Example
package main

import (
	"fmt"
	"maps"

	"github.com/GodsBoss/g/seq/iterate2"
	"github.com/GodsBoss/g/seq/iterate2/pred2"
)

func main() {
	strLengthAtLeast := func(minimum int) func(s string) bool {
		return func(s string) bool {
			return len(s) >= minimum
		}
	}

	values := map[string]string{
		"baz":    "baz",
		"foo":    "foobar",
		"barfoo": "bar",
		"foobar": "barfoo",
	}

	for k, v := range iterate2.Filter(pred2.PassSecondTo[string, string](strLengthAtLeast(5)))(maps.All(values)) {
		fmt.Printf("%s => %s\n", k, v)
	}

}
Output:
foo => foobar
foobar => barfoo

func Unique

func Unique[First comparable, Second comparable]() func(First, Second) bool

Unique returns true for values that had not been passed before, false for others. This filter should be re-created instead of re-used as it holds a map of values that were passed to it. Memory usage grows with values passed to this. Must not be used by multiple sequences concurrently.

Example
package main

import (
	"fmt"

	"github.com/GodsBoss/g/seq/iterate2"
	"github.com/GodsBoss/g/seq/iterate2/pred2"
)

func main() {
	type input struct {
		first  string
		second string
	}

	inputs := []input{
		{
			first:  "foo",
			second: "bar",
		},
		{
			first:  "bar",
			second: "foo",
		},
		{
			first:  "foo",
			second: "bar",
		},
		{
			first:  "baz",
			second: "baz",
		},
	}

	iterator := func() func(yield func(first, second string) bool) {
		index := 0
		return func(yield func(first, second string) bool) {
			for index < len(inputs) {
				if !yield(inputs[index].first, inputs[index].second) {
					return
				}
				index++
			}
		}
	}

	for first, second := range iterate2.Filter(pred2.Unique[string, string]())(iterator()) {
		fmt.Printf("%s-%s\n", first, second)
	}

}
Output:
foo-bar
bar-foo
baz-baz

func UntilCanceled

func UntilCanceled[First any, Second any]() (predicate func(_ First, _ Second) bool, cancel func())

UntilCanceled creates a predicate that holds true until cancel has been called. cancel can be called multiple times, even from different Go routines.

Example
package main

import (
	"fmt"
	"slices"
	"time"

	"github.com/GodsBoss/g/seq/iterate2"
	"github.com/GodsBoss/g/seq/iterate2/pred2"
)

func main() {
	items := []int{2, 3, 5, 7, 11, 13, 17, 19}

	untilCanceled, cancel := pred2.UntilCanceled[int, int]()

	// Cancel after 50 milliseconds.
	go func() {
		time.Sleep(time.Millisecond * 50)
		cancel()
	}()

	for _, n := range iterate2.While(untilCanceled)(slices.All(items)) {
		fmt.Println(n)
		time.Sleep(time.Millisecond * 15)
	}

}
Output:
2
3
5
7

Types

This section is empty.

Jump to

Keyboard shortcuts

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