-
Notifications
You must be signed in to change notification settings - Fork 0
/
sorter.go
127 lines (110 loc) · 2.64 KB
/
sorter.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package dataframe
import (
"sort"
"strconv"
"time"
)
type (
SortType int
SortOption int
)
const (
SortType_String SortType = iota
SortType_Float64
SortType_Duration
)
const (
SortOption_Ascending SortOption = iota
SortOption_Descending
)
// SortBy returns a multiSorter that sorts using the less functions
func SortBy(rows [][]string, lesses ...LessFunc) *MultiSorter {
return &MultiSorter{
data: rows,
less: lesses,
}
}
// LessFunc compares between two string slices.
type LessFunc func(p1, p2 *[]string) bool
func StringAscendingFunc(idx int) func(row1, row2 *[]string) bool {
return func(row1, row2 *[]string) bool {
return (*row1)[idx] < (*row2)[idx]
}
}
func StringDescendingFunc(idx int) func(row1, row2 *[]string) bool {
return func(row1, row2 *[]string) bool {
return (*row1)[idx] > (*row2)[idx]
}
}
func Float64AscendingFunc(idx int) func(row1, row2 *[]string) bool {
return func(row1, row2 *[]string) bool {
v1s := (*row1)[idx]
v1, _ := strconv.ParseFloat(v1s, 64)
v2s := (*row2)[idx]
v2, _ := strconv.ParseFloat(v2s, 64)
return v1 < v2
}
}
func Float64DescendingFunc(idx int) func(row1, row2 *[]string) bool {
return func(row1, row2 *[]string) bool {
v1s := (*row1)[idx]
v1, _ := strconv.ParseFloat(v1s, 64)
v2s := (*row2)[idx]
v2, _ := strconv.ParseFloat(v2s, 64)
return v1 > v2
}
}
func DurationAscendingFunc(idx int) func(row1, row2 *[]string) bool {
return func(row1, row2 *[]string) bool {
v1s := (*row1)[idx]
v1, _ := time.ParseDuration(v1s)
v2s := (*row2)[idx]
v2, _ := time.ParseDuration(v2s)
return v1 < v2
}
}
func DurationDescendingFunc(idx int) func(row1, row2 *[]string) bool {
return func(row1, row2 *[]string) bool {
v1s := (*row1)[idx]
v1, _ := time.ParseDuration(v1s)
v2s := (*row2)[idx]
v2, _ := time.ParseDuration(v2s)
return v1 > v2
}
}
// MultiSorter implements the Sort interface,
// sorting the two dimensional string slices within.
type MultiSorter struct {
data [][]string
less []LessFunc
}
// Sort sorts the rows according to LessFunc.
func (ms *MultiSorter) Sort(rows [][]string) {
sort.Sort(ms)
}
// Len is part of sort.Interface.
func (ms *MultiSorter) Len() int {
return len(ms.data)
}
// Swap is part of sort.Interface.
func (ms *MultiSorter) Swap(i, j int) {
ms.data[i], ms.data[j] = ms.data[j], ms.data[i]
}
// Less is part of sort.Interface.
func (ms *MultiSorter) Less(i, j int) bool {
p, q := &ms.data[i], &ms.data[j]
var k int
for k = 0; k < len(ms.less)-1; k++ {
less := ms.less[k]
switch {
case less(p, q):
// p < q
return true
case less(q, p):
// p > q
return false
}
// p == q; try next comparison
}
return ms.less[k](p, q)
}