What Go gives you
Finding the smallest or the largest value of a slice is a loop you can write by hand: keep the best value so far and compare each new one. Since Go 1.21 the standard slices package does it for you:
slices.Min(s)returns the smallest value of the slices.slices.Max(s)returns the largest value.
Don't confuse them with the built-in min(a, b) and max(a, b), which compare separate values. slices.Max looks at a whole slice at once.
Go has no function that adds up a slice. For a total you write the loop: start a variable at 0 and add each value to it.
Examples
prices := []int{4, 9, 2, 7}
fmt.Println(slices.Min(prices))
fmt.Println(slices.Max(prices))
total := 0
for _, p := range prices {
total += p
}
fmt.Println(total)
This prints:
2
9
22
In the loop, range gives an index and a value for each position. The underscore throws the index away, since an unused variable is a compile error in Go. In a file of your own, add import "slices" alongside fmt.
Other element types
The two functions work on any slice whose items can be compared with <, not only int. With []string{"Rex", "Bo", "Luna"}, slices.Min gives Bo and slices.Max gives Rex, because strings compare in dictionary order. With []float64{3.5, -1.25, 8} they give -1.25 and 8. A slice of structs does not work this way, since structs have no <.
Watch out for an empty slice
slices.Min and slices.Max panic on an empty slice, and the program stops. An empty slice has no smallest value, so there is nothing sensible to return. With a nil or empty slice empty, the call slices.Min(empty) panics with the message slices.Min: empty list. Check len(s) > 0 before calling them when the slice might be empty.
The sum loop needs no such check: over an empty slice it never runs, and total stays at 0, which is the right sum of nothing.
The lesson's task
minutes holds how many minutes you practiced on each day of a week: []int{25, 40, 15, 60, 30, 45, 20}. The task is to store the shortest day in shortest, the longest in longest, and the week's total in total. The code at the bottom prints all three.
- Declare
shortestwith:=andslices.Min(minutes). - Declare
longestthe same way withslices.Max(minutes). - Create
totaland start it at 0. - Loop over
minuteswithfor _, m := range minutes. - Inside the loop, add
mtototal.
minutes := []int{25, 40, 15, 60, 30, 45, 20}
shortest := slices.Min(minutes)
longest := slices.Max(minutes)
total := 0
for _, m := range minutes {
total += m
}
fmt.Println("shortest =", shortest)
fmt.Println("longest =", longest)
fmt.Println("total =", total)
Its output is:
shortest = 15
longest = 60
total = 235
The total is 25 + 40 + 15 + 60 + 30 + 45 + 20 = 235.
Common mistakes
- Calling
slices.Sum. It doesn't exist. Use the loop. - Starting
totalat the first value and then looping over the whole slice. The first value is counted twice. - Writing
total = 0without declaring it. Usetotal := 0the first time. - Passing separate numbers.
slices.Min(3, 5)is a compile error; it takes one slice.
Key takeaways
slices.Min(s)andslices.Max(s)replace a hand-written loop for the extremes.- Both panic on an empty slice, so check the length when the slice may be empty.
- Go has no sum function: add the values in a loop that starts at 0.
