-
Notifications
You must be signed in to change notification settings - Fork 0
/
keysort.go
74 lines (64 loc) · 1.83 KB
/
keysort.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// package keysort implements sorting of sequences (slices) by defined rules
package keysort
import (
"reflect"
"sort"
)
type Sortable interface {
Less(other Sortable) bool
}
// Sort will sort slice by comparing key function values
func Sort(slice interface{}, key func(i int) Sortable) {
sort.Slice(slice, func(i, j int) bool {
return key(i).Less(key(j))
})
}
// StringDesc defines string type sorting in reverse order
type StringDesc string
func (s StringDesc) Less(other Sortable) bool {
others := other.(StringDesc)
return s > others
}
// BoolDesc defines bool type sorting in reverse order
type BoolDesc bool
func (s BoolDesc) Less(other Sortable) bool {
others := other.(BoolDesc)
return bool(s) && !bool(others)
}
type Sequence []interface{}
func (s Sequence) Less(other Sortable) bool {
lhs := s
rhs := other.(Sequence)
if len(lhs) == 0 {
return true
}
if len(rhs) == 0 {
return false
}
if lhs[0] == rhs[0] {
return lhs[1:].Less(rhs[1:])
}
if l, ok := lhs[0].(Sortable); ok {
if r, ok := rhs[0].(Sortable); ok {
return l.Less(r)
}
}
if reflect.TypeOf(lhs[0]) == reflect.TypeOf(rhs[0]) {
switch reflect.TypeOf(lhs[0]).Kind() {
case reflect.String:
return lhs[0].(string) < rhs[0].(string)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return reflect.ValueOf(lhs[0]).Uint() < reflect.ValueOf(rhs[0]).Uint()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return reflect.ValueOf(lhs[0]).Int() < reflect.ValueOf(rhs[0]).Int()
case reflect.Float32, reflect.Float64:
return reflect.ValueOf(lhs[0]).Float() < reflect.ValueOf(rhs[0]).Float()
case reflect.Bool:
return !lhs[0].(bool) && rhs[0].(bool)
default:
panic("Unsupported type")
}
} else {
return reflect.TypeOf(lhs[0]).String() < reflect.TypeOf(rhs[0]).String()
}
}