Golang slices.IndexFunc
last modified April 20, 2025
This tutorial explains how to use the slices.IndexFunc
function in Go.
We'll cover slice operations with practical examples of finding elements.
The slices.IndexFunc function searches for the first element in a slice that satisfies a given condition. It returns the index of the first match.
If no element satisfies the condition, it returns -1. This function is useful for custom element searches in slices of any type.
Basic slices.IndexFunc Example
The simplest use of slices.IndexFunc
finds the first negative number
in a slice. We define a test function to check each element.
package main import ( "fmt" "slices" ) func main() { numbers := []int{1, 2, -3, 4, 5} idx := slices.IndexFunc(numbers, func(n int) bool { return n < 0 }) fmt.Println("First negative at index:", idx) }
We search for the first number less than zero. The function returns index 2 where -3 is located. The anonymous function defines our search condition.
Finding Strings with Specific Properties
slices.IndexFunc
can find strings with specific characteristics.
This example locates the first string starting with 'b'.
package main import ( "fmt" "slices" "strings" ) func main() { words := []string{"apple", "banana", "cherry", "blueberry"} idx := slices.IndexFunc(words, func(s string) bool { return strings.HasPrefix(s, "b") }) fmt.Println("First 'b' word at index:", idx) }
The test function uses strings.HasPrefix
to check each string.
It returns index 1 where "banana" is found, the first matching element.
Searching Struct Slices
We can use slices.IndexFunc
with custom struct types. This example
finds the first person under 18 in a slice.
package main import ( "fmt" "slices" ) type Person struct { Name string Age int } func main() { people := []Person{ {"Alice", 25}, {"Bob", 30}, {"Charlie", 17}, {"Dave", 16}, } idx := slices.IndexFunc(people, func(p Person) bool { return p.Age < 18 }) fmt.Println("First minor at index:", idx) }
The function checks each person's age field. It returns index 2 where Charlie is found, even though Dave is also under 18.
Case-Insensitive String Search
This example demonstrates case-insensitive search using IndexFunc
.
We find the first occurrence of "go" regardless of case.
package main import ( "fmt" "slices" "strings" ) func main() { langs := []string{"Python", "Go", "Rust", "GO", "Java"} idx := slices.IndexFunc(langs, func(s string) bool { return strings.EqualFold(s, "go") }) fmt.Println("First 'go' at index:", idx) }
strings.EqualFold
performs case-insensitive comparison. The function
returns index 1 where "Go" is found, ignoring the later "GO" at index 3.
Finding Elements with Multiple Conditions
Complex conditions can be combined in the test function. This example finds the first even number greater than 10.
package main import ( "fmt" "slices" ) func main() { numbers := []int{5, 8, 12, 7, 14, 9} idx := slices.IndexFunc(numbers, func(n int) bool { return n > 10 && n%2 == 0 }) fmt.Println("First even >10 at index:", idx) }
The condition combines two checks using logical AND. It returns index 2 where 12 is found, the first number satisfying both conditions.
Handling No Matches
When no elements satisfy the condition, IndexFunc
returns -1.
This example demonstrates handling the no-match case.
package main import ( "fmt" "slices" ) func main() { numbers := []int{1, 3, 5, 7, 9} idx := slices.IndexFunc(numbers, func(n int) bool { return n%2 == 0 }) if idx == -1 { fmt.Println("No even numbers found") } else { fmt.Println("First even at index:", idx) } }
Since the slice contains only odd numbers, the function returns -1. We check this value to handle the no-match case appropriately.
Practical Example: Finding Available Port
This practical example uses IndexFunc
to find the first available
port from a list of used ports.
package main import ( "fmt" "slices" ) func main() { usedPorts := []int{80, 443, 8080, 3000, 8000} availablePorts := []int{3000, 4000, 5000, 8080, 9000} idx := slices.IndexFunc(availablePorts, func(p int) bool { return !slices.Contains(usedPorts, p) }) if idx != -1 { fmt.Printf("First available port: %d at index %d\n", availablePorts[idx], idx) } else { fmt.Println("No available ports found") } }
We search for the first port in availablePorts that isn't in usedPorts. The function returns index 1 where port 4000 is found as available.
Source
Go experimental slices package documentation
This tutorial covered the slices.IndexFunc
function in Go with
practical examples of finding elements in slices with custom conditions.
Author
List all Go tutorials.