-
Notifications
You must be signed in to change notification settings - Fork 0
/
orderby.go
61 lines (56 loc) · 1.55 KB
/
orderby.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
package linq
import (
"sort"
"golang.org/x/exp/constraints"
)
func (q Query[T]) HasOrder() bool {
return q.lesser != nil
}
func OrderBy[T any, K constraints.Ordered](q Query[T], key func(t T) K) Query[T] {
return orderByLesser(q, func(data []T) func(i, j int) bool {
return func(i, j int) bool {
return key(data[i]) < key(data[j])
}
})
}
func OrderByDescending[T any, K constraints.Ordered](q Query[T], key func(t T) K) Query[T] {
return orderByLesser(q, func(data []T) func(i, j int) bool {
return func(i, j int) bool {
return key(data[i]) > key(data[j])
}
})
}
func ThenBy[T any, K constraints.Ordered](q Query[T], key func(t T) K) Query[T] {
lesser := q.lesser
return orderByLesser(q, chainLessers(lesser, func(data []T) func(i, j int) bool {
return func(i, j int) bool {
return key(data[i]) < key(data[j])
}
}))
}
func ThenByDescending[T any, K constraints.Ordered](q Query[T], key func(t T) K) Query[T] {
lesser := q.lesser
return orderByLesser(q, chainLessers(lesser, func(data []T) func(i, j int) bool {
return func(i, j int) bool {
return key(data[i]) > key(data[j])
}
}))
}
func chainLessers[T any](a, b lesserFunc[T]) lesserFunc[T] {
return func(data []T) func(i, j int) bool {
a, b := a(data), b(data)
return func(i, j int) bool {
return a(i, j) || !a(j, i) && b(i, j)
}
}
}
func orderByLesser[T any](q Query[T], lesser lesserFunc[T]) Query[T] {
return Query[T]{
lesser: lesser,
iterate: func() func() (T, bool) {
data := q.ToSlice()
sort.Slice(data, lesser(data))
return From(data).iterate()
},
}
}