Use generic function to compute median

This commit is contained in:
Holger Obermaier 2023-08-17 14:46:22 +02:00
parent fcda7a6921
commit eafeea1a76

View File

@ -4,7 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"regexp" "regexp"
"sort" "slices"
"strings" "strings"
topo "github.com/ClusterCockpit/cc-metric-collector/pkg/ccTopology" topo "github.com/ClusterCockpit/cc-metric-collector/pkg/ccTopology"
@ -135,27 +135,47 @@ func maxfunc(args interface{}) (interface{}, error) {
} }
} }
func medianAnyType[T float64 | float32 | int | int32 | int64](values []T) (T, error) {
if len(values) == 0 {
return 0.0, errors.New("median function requires at least one argument")
}
slices.SortFunc(
values,
func(a T, b T) int {
if a < b {
return -1
} else if a > b {
return 1
} else {
return 0
}
},
)
var median T
if midPoint := len(values) % 2; midPoint == 0 {
median = (values[midPoint-1] + values[midPoint]) / 2
} else {
median = values[midPoint]
}
return median, nil
}
// Get the median value // Get the median value
func medianfunc(args interface{}) (interface{}, error) { func medianfunc(args interface{}) (interface{}, error) {
switch values := args.(type) { switch values := args.(type) {
case []float64: case []float64:
sort.Float64s(values) return medianAnyType(values)
return values[len(values)/2], nil case []float32:
// case []float32: return medianAnyType(values)
// sort.Float64s(values)
// return values[len(values)/2], nil
case []int: case []int:
sort.Ints(values) return medianAnyType(values)
return values[len(values)/2], nil case []int64:
return medianAnyType(values)
// case []int64: case []int32:
// sort.Ints(values) return medianAnyType(values)
// return values[len(values)/2], nil default:
// case []int32: return 0.0, errors.New("function 'median' only on list of values (float64, float32, int, int32, int64)")
// sort.Ints(values)
// return values[len(values)/2], nil
} }
return 0.0, errors.New("function 'median()' only on lists of type float64 and int")
} }
/* /*