go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/fu/less.go (about)

     1  package fu
     2  
     3  import (
     4  	"reflect"
     5  )
     6  
     7  /*
     8  Less compares two values and returns true if the left value is less than right one otherwise it returns false
     9  */
    10  func Less(a, b reflect.Value) bool {
    11  	if a.Kind() != b.Kind() {
    12  		panic("values must have the same type")
    13  	}
    14  	if m := a.MethodByName("Less"); m.IsValid() {
    15  		t := m.Type()
    16  		if t.NumOut() == 1 && t.NumIn() == 1 && t.Out(0).Kind() == reflect.Bool && t.In(0) == a.Type() {
    17  			return m.Call([]reflect.Value{b})[0].Bool()
    18  		}
    19  	}
    20  	switch a.Kind() {
    21  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    22  		return a.Int() < b.Int()
    23  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
    24  		return a.Uint() < b.Uint()
    25  	case reflect.Float32, reflect.Float64:
    26  		return a.Float() < b.Float()
    27  	case reflect.String:
    28  		return a.String() < b.String()
    29  	case reflect.Ptr, reflect.Interface:
    30  		if a.IsNil() && !b.IsNil() {
    31  			return true
    32  		} else if b.IsNil() {
    33  			return false
    34  		}
    35  		return Less(a.Elem(), b.Elem())
    36  	case reflect.Struct:
    37  		N := a.NumField()
    38  		for i := 0; i < N; i++ {
    39  			if Less(a.Field(i), b.Field(i)) {
    40  				return true
    41  			} else if Less(b.Field(i), a.Field(i)) {
    42  				return false
    43  			}
    44  		}
    45  		return false
    46  	case reflect.Array:
    47  		if a.Len() != b.Len() {
    48  			panic("values must have the same type")
    49  		}
    50  		N := a.Len()
    51  		for i := 0; i < N; i++ {
    52  			if Less(a.Index(i), b.Index(i)) {
    53  				return true
    54  			} else if Less(b.Index(i), a.Index(i)) {
    55  				return false
    56  			}
    57  		}
    58  		return false
    59  	default:
    60  		panic("only int,float,string,struct,array are allowed to compare")
    61  	}
    62  }