More than 10 years later, I'm wondering why I can't find anything better than a manual for loop in order to filter some data from a list.
I've came to create custom helper functions for this, as follows:
// Filter the slice based on the predicate and return the result
func filter[S ~[]T, T any](slice S, predicate func(T) bool) []T {
out := make([]T, 0)
for _, item := range slice {
if predicate(item) {
out = append(out, item)
}
}
return out
}
// For cases where you have to filter the slice and also keep the items that do not match the predicate
func filterOr[S ~[]T, T any](slice S, predicate func(T) bool) ([]T, []T) {
out := make([]T, 0)
orOut := make([]T, 0)
for _, item := range slice {
if predicate(item) {
out = append(out, item)
} else {
orOut = append(orOut, item)
}
}
return out, orOut
}
They can then be used like this:
package main
import "fmt"
func isEven(num int) bool { return num%2 == 0 }
func main() {
initialSlice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
evenNumbers1 := filter(initialSlice, isEven)
// Even numbers: [2 4 6 8 10]
fmt.Printf("Even numbers: %v\n", evenNumbers1)
evenNumbers2, oddNumbers := filterOr(initialSlice, isEven)
// Even numbers: [2 4 6 8 10]
fmt.Printf("Even numbers: %v\n", evenNumbers2)
// Odd numbers: [1 3 5 7 9]
fmt.Printf("Odd numbers: %v\n", oddNumbers)
}
Thanks to this, my code is a little less bloated.