github.com/mymmsc/gox@v1.3.33/util/lambda/compare.go (about)

     1  package lambda
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"math"
     7  	"reflect"
     8  	"strings"
     9  )
    10  
    11  func BasicComparator(ele interface{}) (Compare, error) {
    12  	if c, ok := ele.(Compare); ok {
    13  		return c, nil
    14  	}
    15  
    16  	k := reflect.TypeOf(ele).Kind()
    17  
    18  	support := []reflect.Kind{
    19  		reflect.Int,
    20  		reflect.Uint8,
    21  		reflect.Uint16,
    22  		reflect.Uint32,
    23  		reflect.Uint64,
    24  		reflect.Int8,
    25  		reflect.Int16,
    26  		reflect.Uint32,
    27  		reflect.Int64,
    28  		reflect.Float32,
    29  		reflect.Float64,
    30  		reflect.String,
    31  	}
    32  	if contain(support, k) {
    33  		return &BasicCompare{ele}, nil
    34  	}
    35  
    36  	return nil, errors.New("unknown type")
    37  }
    38  
    39  func contain(kinds []reflect.Kind, target reflect.Kind) bool {
    40  	for _, k := range kinds {
    41  		if k == target {
    42  			return true
    43  		}
    44  	}
    45  	return false
    46  }
    47  
    48  type Compare interface {
    49  	CompareTo(a interface{}) int
    50  }
    51  
    52  type BasicCompare struct {
    53  	v interface{}
    54  }
    55  
    56  func (p *BasicCompare) CompareTo(a interface{}) int {
    57  
    58  	vt, at := reflect.TypeOf(p.v), reflect.TypeOf(a)
    59  	if vt.Kind() != at.Kind() {
    60  		panic(fmt.Sprintf("%s is not %s", vt.String(), at.String()))
    61  	}
    62  
    63  	switch p.v.(type) {
    64  	case int:
    65  		return p.v.(int) - a.(int)
    66  	case uint8:
    67  		return int(p.v.(uint8) - a.(uint8))
    68  	case uint16:
    69  		return int(p.v.(uint16) - a.(uint16))
    70  	case uint32:
    71  		return int(p.v.(uint32) - a.(uint32))
    72  	case uint64:
    73  		return int(p.v.(uint64) - a.(uint64))
    74  	case int8:
    75  		return int(p.v.(int8) - a.(int8))
    76  	case int16:
    77  		return int(p.v.(int16) - a.(int16))
    78  	case int32:
    79  		return int(p.v.(int32) - a.(int32))
    80  	case int64:
    81  		return int(p.v.(int64) - a.(int64))
    82  	case float32:
    83  		v := p.v.(float32) - a.(float32)
    84  		if v > 0 {
    85  			return int(math.Ceil(float64(v)))
    86  		} else if v == 0 {
    87  			return 0
    88  		} else {
    89  			return int(math.Floor(float64(v)))
    90  		}
    91  
    92  	case float64:
    93  		v := p.v.(float64) - a.(float64)
    94  		if v > 0 {
    95  			return int(math.Ceil(v))
    96  		} else if v == 0 {
    97  			return 0
    98  		} else {
    99  			return int(math.Floor(v))
   100  		}
   101  	case string:
   102  		return strings.Compare(p.v.(string), a.(string))
   103  	default:
   104  		panic("unknown type " + at.String())
   105  	}
   106  }