0
package main

import (
    "fmt"
)

func findMinMax[T comparable](arr []T) (min, max T) {
    for _, v := range arr {
        if v > max {
            max = v
        } else if v < min {
            min = v
        }
    }
    return min, max
}

func main() {
    arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    fmt.Println(findMinMax(arr))
}

I would be more than happy to help you resolve the issue you are facing in the findMinMax function. The error message indicating that v > max or v < min suggests that there might be a problem with the comparison operation within the function. In order to offer a precise solution, I would need to see the implementation of the findMinMax function. Based on your description, it seems that the type T, which is supposed to be comparable, is causing the issue during comparison.

I am expecting the function findMinMax will work correctly.

  • 1
    replace `comparable ` to `constraints.Ordered`. The `comparable` constraint only enables using `==` and `!=` operators for comparison. And your `max` and `min` should init with `arr[0]`. – Trock Aug 02 '23 at 12:11

1 Answers1

1

You used the comarable constraint for the T type parameter. comparable means that: comparable. So you can use the == operator on values of that type. It doesn't mean they are ordered, which is required to use the < > operators.

The ordered constraint is defined in the golang.org/x/exp/constraints package, see constraints.Ordered.

Using that your code compiles:

import (
    "fmt"

    "golang.org/x/exp/constraints"
)

func findMinMax[T constraints.Ordered](arr []T) (min, max T) {
    for _, v := range arr {
        if v > max {
            max = v
        } else if v < min {
            min = v
        }
    }
    return min, max
}

Try it on the Go Playground.

It gives wrong result though, as you're starting min and max from their zero values, and if all values in the passed slice are greater than or less than the zero value, min or max will remain the zero value.

An easy fix is to initialize min and max with the first value if the passed slice is not empty:

func findMinMax[T constraints.Ordered](arr []T) (min, max T) {
    if len(arr) > 0 {
        min, max = arr[0], arr[0]
    }

    for _, v := range arr {
        if v > max {
            max = v
        } else if v < min {
            min = v
        }
    }
    return min, max
}

This will output (try it on the Go Playground):

1 9

Note if you're working with floating point types, you have to explicitly handle NaN values as their order to other floats is not specified.

icza
  • 389,944
  • 63
  • 907
  • 827
  • 1
    Broken if T is a float an arr[0] is a NaN. – Volker Aug 02 '23 at 12:33
  • 1
    @Volker You're right, thanks. Added a note to the end of the answer. – icza Aug 02 '23 at 12:42
  • Thank you but now is another error, that in my VSCODE it doesn't contain "golang.org/x/exp/constraints". I tried to use these but it is still not working: go clean -modcache go install -v golang.org/x/tools/gopls@latest – twentyfourk Aug 02 '23 at 12:48
  • 2
    @twentyfourk: you need to add that package to your project with `go get`, or just copy [the interface implementation](https://pkg.go.dev/golang.org/x/exp/constraints#Ordered) – JimB Aug 02 '23 at 12:53