ZetCode

Go predicate

last modified April 11, 2024

In this article we show how to work with predicates in Golang.

$ go version
go version go1.22.2 linux/amd64

We use Go version 1.22.2.

A predicate in general meaning is a statement about something that is either true or false. In programming, predicates represent single argument functions that return a boolean value.

Go simple predicate example

In the next example, we have a simple predicate.

main.go
package main

import (
    "fmt"
)

func isPositive(val int) bool {

    if val > 0 {

        return true
    } else {

        return false
    }
}

func main() {

    vals := []int{-2, 0, 4, 3, 1, 9, 7, -3, -5, 6}
    vals2 := []int{}

    for _, val := range vals {

        if isPositive(val) {

            vals2 = append(vals2, val)
        }
    }

    fmt.Println(vals)
    fmt.Println(vals2)
}

The example takes all positive numbers from a slice into another slice.

func isPositive(val int) bool {

    if val > 0 {

        return true
    } else {

        return false
    }
}

The isPositive function is a predicate. It returns a boolean value indicating whether a value is positive.

for _, val := range vals {

    if isPositive(val) {

        vals2 = append(vals2, val)
    }
}

We go through the slice of values and apply the predicat on each of the elements.

$ go run main.go
[-2 0 4 3 1 9 7 -3 -5 6]
[4 3 1 9 7 6]

Go any function

The any (also called exists) function iterates over elements of a collection and returns true if the predicate is valid for at least one element.

main.go
package main

import (
    "fmt"
    "strings"
)

func any(data []string, f func(string) bool) bool {

    for _, v := range data {

        if f(v) {
            return true
        }
    }

    return false
}

func main() {

    words := []string{"falcon", "war", "sun", "cup", "rock"}

    w := "e"
    r := any(words, func(s string) bool {

        return strings.Contains(s, w)
    })

    if r {

        fmt.Printf("The slice contains an element with %s\n", w)
    } else {

        fmt.Printf("The slice does not contain an element with %s\n", w)
    }
}

In the example we use the any function to check if at least one word of the words slice has letter 'w'.

func any(data []string, f func(string) bool) bool {

    for _, v := range data {

        if f(v) {
            return true
        }
    }

    return false
}

The any is a function that takes a slice and a predicate as parameters.

r := any(words, func(s string) bool {

    return strings.Contains(s, w)
})

The predicate is an anonymous function which utilizes the strings.Contains function.

$ go run main.go
The slice does not contain an element with e

Go all function

The all function iterates over elements of a collection and returns true if the predicate is valid for all elements.

main.go
package main

import "fmt"

func all(data []string, f func(string) bool) bool {

    for _, e := range data {

        if !f(e) {

            return false
        }
    }

    return true
}

func main() {

    words := []string{"war", "water", "cup", "tree", "storm"}
    n := 3

    res := all(words, func(s string) bool {

        return len(s) >= n
    })

    if res {

        fmt.Printf("All words have %d+ characters", n)
    } else {

        fmt.Printf("It is not true that all words have %d+ characters", n)
    }
}

In the example we use the all function to check if all words have n or more letters.

$ go run main.go
All words have 3+ characters

Go filter function

The filter function returns a new collection containing only the elements of the collection for which the given predicate returns true.

main.go
package main

import (
    "fmt"
    "strings"
)

func filter(data []string, f func(string) bool) []string {

    fltd := make([]string, 0)

    for _, e := range data {

        if f(e) {
            fltd = append(fltd, e)
        }
    }

    return fltd
}

func main() {

    words := []string{"war", "water", "cup", "tree", "storm"}

    p := "w"

    res := filter(words, func(s string) bool {

        return strings.HasPrefix(s, p)
    })

    fmt.Println(res)
}

The example uses the filter function to find all words that start with 'w'.

func filter(data []string, f func(string) bool) []string {

    fltd := make([]string, 0)

    for _, e := range data {

        if f(e) {
            fltd = append(fltd, e)
        }
    }

    return fltd
}

The filter function takes the collection and the predicate as parameters. It creates a new fltd slice into which we append all the elements that satisfy the passed predicate function.

$ go run main.go
[war water]

Source

The Go Programming Language Specification

In this article we have covered predicates in Golang.

Author

My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Go tutorials.