package main import ( "fmt" "strconv" ) // Maps over collection of T and applies function f to each item // Returns a new slice with the transformed items func mapf[T any, U any](items []T, f func(T) U) []U { transformed := make([]U, 0, len(items)) for _, n := range items { transformed = append(transformed, f(n)) } return transformed } // for which the provided function returns true. func filter[T any](items []T, predicate func(T) bool) []T { var result []T for _, item := range items { if predicate(item) { result = append(result, item) } } return result } func main() { func1 := func(n int) int { return n + 1 } numbers := []int{1, 2, 3, 4} fmt.Println(mapf(numbers, func1)) func2 := func(n int) int { return n * 2 } fmt.Println(mapf(numbers, func2)) strings := []string{"1", "2", "3", "oink"} // Using an anonymous function fmt.Println(mapf(strings, func(st string) string { return st + "!!" })) fmt.Println(mapf(strings, func(st string) int { i, err := strconv.Atoi(st) if err != nil { return 99 // or handle the error differently } return i })) fmt.Println(filter(numbers, func(n int) bool { return n%2 == 0 })) fmt.Println(filter(mapf(strings, func(st string) int { i, _ := strconv.Atoi(st) return i }), func(n int) bool { return n > 0 })) }