To count the elements in a slice in Go that satisfy a certain condition, it is best to use Generics available since Go 1.18. With it, we can create a function that takes as arguments a slice of any type and a filter function that returns true
or false
for an element of that slice. In this way, we get a universal function that, for any slice, counts the occurrences of elements that meet any condition.
package main
import (
"fmt"
"strings"
)
func count[T any](slice []T, f func(T) bool) int {
count := 0
for _, s := range slice {
if f(s) {
count++
}
}
return count
}
func main() {
s := []string{"ab", "ac", "de", "at", "gfb", "fr"}
fmt.Println(
count(
s,
func(x string) bool {
return strings.Contains(x, "a")
}),
)
s2 := []int{1, 2, 3, 4, 5, 6}
fmt.Println(
count(
s2,
func(x int) bool {
return x%3 == 0
}),
)
}
As you can see in the example, the count()
function accepts a slice of a type parameter T
, whose constraint is any
- that is, it can be a slice of any type. The body of the function is simple. If the function f()
returns true
for a given slice element then the counter count
increases by 1.
In the main()
, you can see how versatile the count()
function is. In the first case, we put a string slice as an argument and count the number of elements that contain the letter "a"
. In the second case, we put an int
slice and count the number of records divisible by 3. It is how the magic of Go Generics works. You do not need to write separate functions for each type - one is sufficient for all cases.