mirror of
https://github.com/metabarcoding/obitools4.git
synced 2026-06-24 09:41:00 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4dae7f708d | |||
| 578445f38a | |||
| 2edb33ad08 | |||
| b108d4978e | |||
| e9210e28a3 | |||
| 13a93fce11 | |||
| 14064c919e | |||
| 1dfd68aa6d |
@@ -3,7 +3,7 @@ package obioptions
|
||||
// Version is automatically updated by the Makefile from version.txt
|
||||
// The patch number (third digit) is incremented on each push to the repository
|
||||
|
||||
var _Version = "Release 4.4.43"
|
||||
var _Version = "Release 4.4.45"
|
||||
|
||||
// Version returns the version of the obitools package.
|
||||
//
|
||||
|
||||
@@ -141,6 +141,20 @@ var OBILang = gval.NewLanguage(
|
||||
gval.Function("max", func(args ...interface{}) (interface{}, error) {
|
||||
return obiutils.Max(args[0])
|
||||
}),
|
||||
gval.Function("whichmax", func(args ...interface{}) (interface{}, error) {
|
||||
result, err := obiutils.WhichMax(args[0])
|
||||
if idx, ok := result.(int); ok {
|
||||
return float64(idx), nil
|
||||
}
|
||||
return result, err
|
||||
}),
|
||||
gval.Function("whichmin", func(args ...interface{}) (interface{}, error) {
|
||||
result, err := obiutils.WhichMin(args[0])
|
||||
if idx, ok := result.(int); ok {
|
||||
return float64(idx), nil
|
||||
}
|
||||
return result, err
|
||||
}),
|
||||
|
||||
gval.Function("filtermin", func(args ...interface{}) (interface{}, error) {
|
||||
return obiutils.FilterMin(args[0], args[1])
|
||||
|
||||
+128
-8
@@ -309,7 +309,7 @@ func saturatingSubValues(a, b reflect.Value) (reflect.Value, error) {
|
||||
func maxFromIterable(v reflect.Value) (interface{}, error) {
|
||||
var best reflect.Value
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
elem := v.Index(i)
|
||||
elem := unwrapInterface(v.Index(i))
|
||||
if !isOrderedKind(elem.Kind()) {
|
||||
return nil, fmt.Errorf("unsupported element type: %s", elem.Kind())
|
||||
}
|
||||
@@ -324,7 +324,7 @@ func maxFromIterable(v reflect.Value) (interface{}, error) {
|
||||
func minFromIterable(v reflect.Value) (interface{}, error) {
|
||||
var minVal reflect.Value
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
elem := v.Index(i)
|
||||
elem := unwrapInterface(v.Index(i))
|
||||
if !isOrderedKind(elem.Kind()) {
|
||||
return nil, fmt.Errorf("unsupported element type: %s", elem.Kind())
|
||||
}
|
||||
@@ -339,7 +339,7 @@ func filterMinFromIterable(v reflect.Value, minimum interface{}) (interface{}, e
|
||||
minVal := reflect.ValueOf(minimum)
|
||||
result := reflect.MakeSlice(v.Type(), 0, v.Len())
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
elem := v.Index(i)
|
||||
elem := unwrapInterface(v.Index(i))
|
||||
if !isOrderedKind(elem.Kind()) {
|
||||
return nil, fmt.Errorf("unsupported element type: %s", elem.Kind())
|
||||
}
|
||||
@@ -354,7 +354,7 @@ func filterMaxFromIterable(v reflect.Value, maximum interface{}) (interface{}, e
|
||||
maxVal := reflect.ValueOf(maximum)
|
||||
result := reflect.MakeSlice(v.Type(), 0, v.Len())
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
elem := v.Index(i)
|
||||
elem := unwrapInterface(v.Index(i))
|
||||
if !isOrderedKind(elem.Kind()) {
|
||||
return nil, fmt.Errorf("unsupported element type: %s", elem.Kind())
|
||||
}
|
||||
@@ -365,11 +365,121 @@ func filterMaxFromIterable(v reflect.Value, maximum interface{}) (interface{}, e
|
||||
return result.Interface(), nil
|
||||
}
|
||||
|
||||
// whichMaxFromIterable returns the index of the maximum element in a slice/array.
|
||||
func whichMaxFromIterable(v reflect.Value) (int, error) {
|
||||
var best reflect.Value
|
||||
bestIdx := 0
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
elem := unwrapInterface(v.Index(i))
|
||||
if !isOrderedKind(elem.Kind()) {
|
||||
return 0, fmt.Errorf("unsupported element type: %s", elem.Kind())
|
||||
}
|
||||
if i == 0 || greater(elem, best) {
|
||||
best = elem
|
||||
bestIdx = i
|
||||
}
|
||||
}
|
||||
return bestIdx, nil
|
||||
}
|
||||
|
||||
// whichMinFromIterable returns the index of the minimum element in a slice/array.
|
||||
func whichMinFromIterable(v reflect.Value) (int, error) {
|
||||
var minVal reflect.Value
|
||||
minIdx := 0
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
elem := unwrapInterface(v.Index(i))
|
||||
if !isOrderedKind(elem.Kind()) {
|
||||
return 0, fmt.Errorf("unsupported element type: %s", elem.Kind())
|
||||
}
|
||||
if i == 0 || less(elem, minVal) {
|
||||
minVal = elem
|
||||
minIdx = i
|
||||
}
|
||||
}
|
||||
return minIdx, nil
|
||||
}
|
||||
|
||||
// whichMaxFromMap returns the key associated with the maximum value in a map.
|
||||
func whichMaxFromMap(v reflect.Value) (interface{}, error) {
|
||||
var best reflect.Value
|
||||
var bestKey reflect.Value
|
||||
first := true
|
||||
for _, key := range v.MapKeys() {
|
||||
elem := unwrapInterface(v.MapIndex(key))
|
||||
if !isOrderedKind(elem.Kind()) {
|
||||
return nil, fmt.Errorf("unsupported element type: %s", elem.Kind())
|
||||
}
|
||||
if first || greater(elem, best) {
|
||||
best = elem
|
||||
bestKey = key
|
||||
first = false
|
||||
}
|
||||
}
|
||||
return bestKey.Interface(), nil
|
||||
}
|
||||
|
||||
// whichMinFromMap returns the key associated with the minimum value in a map.
|
||||
func whichMinFromMap(v reflect.Value) (interface{}, error) {
|
||||
var minVal reflect.Value
|
||||
var minKey reflect.Value
|
||||
first := true
|
||||
for _, key := range v.MapKeys() {
|
||||
elem := unwrapInterface(v.MapIndex(key))
|
||||
if !isOrderedKind(elem.Kind()) {
|
||||
return nil, fmt.Errorf("unsupported element type: %s", elem.Kind())
|
||||
}
|
||||
if first || less(elem, minVal) {
|
||||
minVal = elem
|
||||
minKey = key
|
||||
first = false
|
||||
}
|
||||
}
|
||||
return minKey.Interface(), nil
|
||||
}
|
||||
|
||||
// WhichMax returns the key (for a map) or index (for a slice/array) of the maximum value.
|
||||
func WhichMax(data interface{}) (interface{}, error) {
|
||||
v := reflect.ValueOf(data)
|
||||
switch v.Kind() {
|
||||
case reflect.Slice, reflect.Array:
|
||||
if v.Len() == 0 {
|
||||
return nil, errors.New("empty slice or array")
|
||||
}
|
||||
return whichMaxFromIterable(v)
|
||||
case reflect.Map:
|
||||
if v.Len() == 0 {
|
||||
return nil, errors.New("empty map")
|
||||
}
|
||||
return whichMaxFromMap(v)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported type: %s", v.Kind())
|
||||
}
|
||||
}
|
||||
|
||||
// WhichMin returns the key (for a map) or index (for a slice/array) of the minimum value.
|
||||
func WhichMin(data interface{}) (interface{}, error) {
|
||||
v := reflect.ValueOf(data)
|
||||
switch v.Kind() {
|
||||
case reflect.Slice, reflect.Array:
|
||||
if v.Len() == 0 {
|
||||
return nil, errors.New("empty slice or array")
|
||||
}
|
||||
return whichMinFromIterable(v)
|
||||
case reflect.Map:
|
||||
if v.Len() == 0 {
|
||||
return nil, errors.New("empty map")
|
||||
}
|
||||
return whichMinFromMap(v)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported type: %s", v.Kind())
|
||||
}
|
||||
}
|
||||
|
||||
func filterMinFromMap(v reflect.Value, minimum interface{}) (interface{}, error) {
|
||||
minVal := reflect.ValueOf(minimum)
|
||||
result := reflect.MakeMap(v.Type())
|
||||
for _, key := range v.MapKeys() {
|
||||
elem := v.MapIndex(key)
|
||||
elem := unwrapInterface(v.MapIndex(key))
|
||||
if !isOrderedKind(elem.Kind()) {
|
||||
return nil, fmt.Errorf("unsupported element type: %s", elem.Kind())
|
||||
}
|
||||
@@ -384,7 +494,7 @@ func filterMaxFromMap(v reflect.Value, maximum interface{}) (interface{}, error)
|
||||
maxVal := reflect.ValueOf(maximum)
|
||||
result := reflect.MakeMap(v.Type())
|
||||
for _, key := range v.MapKeys() {
|
||||
elem := v.MapIndex(key)
|
||||
elem := unwrapInterface(v.MapIndex(key))
|
||||
if !isOrderedKind(elem.Kind()) {
|
||||
return nil, fmt.Errorf("unsupported element type: %s", elem.Kind())
|
||||
}
|
||||
@@ -400,7 +510,7 @@ func maxFromMap(v reflect.Value) (interface{}, error) {
|
||||
var best reflect.Value
|
||||
first := true
|
||||
for _, key := range v.MapKeys() {
|
||||
elem := v.MapIndex(key)
|
||||
elem := unwrapInterface(v.MapIndex(key))
|
||||
if !isOrderedKind(elem.Kind()) {
|
||||
return nil, fmt.Errorf("unsupported element type: %s", elem.Kind())
|
||||
}
|
||||
@@ -417,7 +527,7 @@ func minFromMap(v reflect.Value) (interface{}, error) {
|
||||
var minVal reflect.Value
|
||||
first := true
|
||||
for _, key := range v.MapKeys() {
|
||||
elem := v.MapIndex(key)
|
||||
elem := unwrapInterface(v.MapIndex(key))
|
||||
if !isOrderedKind(elem.Kind()) {
|
||||
return nil, fmt.Errorf("unsupported element type: %s", elem.Kind())
|
||||
}
|
||||
@@ -440,6 +550,16 @@ func isNumericKind(k reflect.Kind) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// unwrapInterface returns v.Elem() when v holds an interface value, otherwise v unchanged.
|
||||
// This is necessary when iterating map[string]interface{} or []interface{} via reflection:
|
||||
// the element Kind is reflect.Interface, not the underlying concrete type.
|
||||
func unwrapInterface(v reflect.Value) reflect.Value {
|
||||
if v.Kind() == reflect.Interface {
|
||||
return v.Elem()
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// isOrderedKind reports whether k supports comparison ordering.
|
||||
func isOrderedKind(k reflect.Kind) bool {
|
||||
switch k {
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
4.4.43
|
||||
4.4.45
|
||||
|
||||
Reference in New Issue
Block a user