自己来排一排 sort.go
代码语言:javascript复制package objsort
// objsort 可以给任意的数组按key排序(like py3), 找min max,就是这么666
import (
"fmt"
"reflect"
"sort"
)
func getLess(arrItem interface{}) func(i, j interface{}) bool {
switch arrItem.(type) {
case string:
return func(left, right interface{}) bool {
return left.(string) < right.(string)
}
case int:
return func(left, right interface{}) bool {
return left.(int) < right.(int)
}
case int8:
return func(left, right interface{}) bool {
return left.(int8) < right.(int8)
}
case int16:
return func(left, right interface{}) bool {
return left.(int16) < right.(int16)
}
case int32:
return func(left, right interface{}) bool {
return left.(int32) < right.(int32)
}
case int64:
return func(left, right interface{}) bool {
return left.(int64) < right.(int64)
}
case float32:
return func(left, right interface{}) bool {
return left.(float32) < right.(float32)
}
case float64:
return func(left, right interface{}) bool {
return left.(float64) < right.(float64)
}
case uint:
return func(left, right interface{}) bool {
return left.(uint) < right.(uint)
}
case uint8:
return func(left, right interface{}) bool {
return left.(uint8) < right.(uint8)
}
case uint16:
return func(left, right interface{}) bool {
return left.(uint16) < right.(uint16)
}
case uint32:
return func(left, right interface{}) bool {
return left.(uint32) < right.(uint32)
}
case uint64:
return func(left, right interface{}) bool {
return left.(uint64) < right.(uint64)
}
}
panic(fmt.Sprintln("暂时不支持的类型", arrItem))
}
var Self = func(v interface{}) interface{} {
return v
}
// 自定义的 Reverse 类型
type keySort struct {
arrKey []interface{}
innerSwapper func(i, j int)
less func(i, j interface{}) bool
len int
}
func (k *keySort) Less(i, j int) bool {
return k.less(k.arrKey[i], k.arrKey[j])
}
func (k *keySort) Swap(i, j int) {
k.arrKey[i], k.arrKey[j] = k.arrKey[j], k.arrKey[i]
k.innerSwapper(i, j)
}
func (k *keySort) Len() int {
return len(k.arrKey)
}
// ByKey 可以排序arr
// arr 是任意的数组,
// key 为给定的函数,提取对象特征做排序依据,必须return int* uint* float* string
// reversed决定结果是否逆序
func ByKey(arr interface{},
key func(interface{}) interface{}, reversed bool) {
switch reflect.TypeOf(arr).Kind() {
case reflect.Slice:
s := reflect.ValueOf(arr)
if s.Len() == 0 || s.Len() == 1 {
return
}
less := getLess(key(s.Index(0).Interface()))
swap := reflect.Swapper(arr)
arrKey := make([]interface{}, 0)
for i := 0; i < s.Len(); i {
arrKey = append(arrKey, key(s.Index(i).Interface()))
}
keysort := new(keySort)
keysort.innerSwapper = swap
keysort.arrKey = arrKey
keysort.less = less
if reversed == true {
sort.Sort(sort.Reverse(keysort))
} else {
sort.Sort(keysort)
}
}
}
func compare(arr interface{},
key func(interface{}) interface{}, isless bool) interface{} {
var target interface{}
switch reflect.TypeOf(arr).Kind() {
case reflect.Slice:
s := reflect.ValueOf(arr)
if s.Len() == 0 {
return nil
}
target = s.Index(0).Interface()
left := key(target)
less := getLess(left)
for i := 0; i < s.Len(); i {
tp := s.Index(i).Interface()
right := key(tp)
// 判定 target 和 tp的大小关系
// 如果isless 为 true 则 target < tp
if less(left, right) == isless {
target = tp
}
}
}
return target
}
func Min(arr interface{},
key func(interface{}) interface{}) interface{} {
return compare(arr, key, false)
}
func Max(arr interface{},
key func(interface{}) interface{}) interface{} {
return compare(arr, key, true)
}
main.go
代码语言:javascript复制package main
import (
"fmt"
"math"
"math/rand"
"objsort"
"sort"
"time"
)
func RndInt(start, end int) int {
du := end - start 1
return start rand.Intn(du)
}
type Point struct {
X int
Y int
}
func main() {
t1 := make([]int, 0)
t2 := make([]int, 0)
for i := 0; i < 100000; i = 1 {
tp := RndInt(0, 99999)
t1 = append(t1, tp)
t2 = append(t2, tp)
}
now := time.Now()
sort.Slice(t1, func(i, j int) bool {
return t1[i] < t1[j]
})
fmt.Println(time.Since(now))
now = time.Now()
fmt.Println(t2[:10])
objsort.ByKey(t2, objsort.Self, false)
fmt.Println(time.Since(now))
fmt.Println(t2[:10])
var arrPoint1 = []Point{
Point{30, 60},
Point{80, 70},
Point{10, 65},
}
objsort.ByKey(arrPoint1, func(i interface{}) interface{} {
obj := i.(Point)
return math.Sqrt(float64(obj.X*obj.X obj.Y*obj.Y))
}, false)
fmt.Println(arrPoint1)
}