Go filter and map
last modified April 11, 2024
In this article we show how to create and use filter and map functions in Golang.
A filter function processes a collection and produces a new collection containing exactly those elements for which the given predicate returns true.
A map function applies a given function to each element of a collection, returning the results in a new collection.
A predicate is a single-argument function which returns a boolean value.
$ go version go version go1.22.2 linux/amd64
We use Go version 1.22.2.
Go filter example
In the next example, we apply the filter function on a slice of strings.
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) }
We have a slice of words. With the help of the filter
function, we
filter out all words that start with 'w' and put them into a new slice.
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 a slice of words and the predicate as
parameters. The predicate is a function that is applied on every slice element.
$ go run main.go [war water]
In the next example, we filter a slice of struct types.
package main import "fmt" type User struct { name string occupation string country string } func filter(data []User, f func(User) bool) []User { fltd := make([]User, 0) for _, user := range data { if f(user) { fltd = append(fltd, user) } } return fltd } func main() { users := []User{ {"John Doe", "gardener", "USA"}, {"Roger Roe", "driver", "UK"}, {"Paul Smith", "programmer", "Canada"}, {"Lucia Mala", "teacher", "Slovakia"}, {"Patrick Connor", "shopkeeper", "USA"}, {"Tim Welson", "programmer", "Canada"}, {"Tomas Smutny", "programmer", "Slovakia"}, } country := "Slovakia" res := filter(users, func(u User) bool { return u.country == country }) fmt.Println(res) }
The example filters all users that live in Slovakia.
$ go run main.go [{Lucia Mala teacher Slovakia} {Tomas Smutny programmer Slovakia}]
Go filter generic example
In the following example, we create a generic version of a filter function.
package main import ( "fmt" "strings" ) func filter[T any](data []T, f func(T) bool) []T { fltd := make([]T, 0, len(data)) for _, e := range data { if f(e) { fltd = append(fltd, e) } } return fltd } func main() { words := []string{"war", "cup", "water", "tree", "storm"} res := filter(words, func(s string) bool { return strings.HasPrefix(s, "w") }) fmt.Println(res) vals := []int{-1, 0, 2, 5, -9, 3, 4, 7} res2 := filter(vals, func(e int) bool { return e > 0 }) fmt.Println(res2) }
We have a generic version of the filter function. We use it to filter strings and integers.
$ go run main.go [war water] [2 5 3 4 7]
Go map example
In the following example, we transform a slice of integers. Note that we cannot name the function map, since it is a Go keyword for creating dictionaries/maps.
package main import ( "fmt" ) func map2(data []int, f func(int) int) []int { mapped := make([]int, len(data)) for i, e := range data { mapped[i] = f(e) } return mapped } func main() { vals := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} res := map2(vals, func(i int) int { return i * i }) fmt.Println(res) }
We have a slice of integers. We square all elements of the slice.
$ go run main.go [1 4 9 16 25 36 49 64 81 100]
In the next example, we apply a map function on a slice of strings.
package main import ( "fmt" "strings" ) func map2(data []string, f func(string) string) []string { mapped := make([]string, len(data)) for i, e := range data { mapped[i] = f(e) } return mapped } func main() { words := []string{"war", "water", "cup", "tree", "storm"} res := map2(words, strings.ToUpper) fmt.Println(res) }
The example transforms a slice of strings into uppercase.
$ go run main.go [WAR WATER CUP TREE STORM]
Go map generic example
In the following example, we have a generic version of the map function.
package main import ( "fmt" "strconv" "strings" ) func map2[T, U any](data []T, f func(T) U) []U { res := make([]U, 0, len(data)) for _, e := range data { res = append(res, f(e)) } return res } func main() { words := []string{"war", "cup", "water", "tree", "storm"} result := map2(words, func(s string) string { return strings.ToUpper(s) }) fmt.Println(result) fmt.Println("-------------------") numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} squares := map2(numbers, func(n int) int { return n * n }) fmt.Println(squares) fmt.Println("-------------------") as_strings := map2(numbers, func(n int) string { return strconv.Itoa(n) }) fmt.Printf("%q", as_strings) }
With the map function, we process integers and strings.
$ go run main.go [WAR CUP WATER TREE STORM] ------------------- [1 4 9 16 25 36 49 64 81 100] ------------------- ["1" "2" "3" "4" "5" "6" "7" "8" "9" "10"]
Source
The Go Programming Language Specification
In this article we have worked with filter and map functions in Golang.
Author
List all Go tutorials.