Learn how to use slices.IndexFunc in Go to find elements in slices with custom conditions. Includes practical examples and use cases.
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.
The simplest use of slices.IndexFunc finds the first negative number in a slice. We define a test function to check each element.
basic_indexfunc.go
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.
slices.IndexFunc can find strings with specific characteristics. This example locates the first string starting with ‘b’.
string_search.go
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.
We can use slices.IndexFunc with custom struct types. This example finds the first person under 18 in a slice.
struct_search.go
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.
This example demonstrates case-insensitive search using IndexFunc. We find the first occurrence of “go” regardless of case.
case_insensitive.go
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.
Complex conditions can be combined in the test function. This example finds the first even number greater than 10.
multiple_conditions.go
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.
When no elements satisfy the condition, IndexFunc returns -1. This example demonstrates handling the no-match case.
no_match.go
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.
This practical example uses IndexFunc to find the first available port from a list of used ports.
port_finder.go
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.
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.
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Go tutorials.