-
Notifications
You must be signed in to change notification settings - Fork 6
/
thenby.go
175 lines (156 loc) · 7.13 KB
/
thenby.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package go2linq
import (
"cmp"
"github.com/solsw/collate"
"github.com/solsw/errorhelper"
)
// Reimplementing LINQ to Objects: Part 26b – OrderBy{,Descending}/ThenBy{,Descending}
// https://codeblog.jonskeet.uk/2011/01/05/reimplementing-linq-to-objects-part-26b-orderby-descending-thenby-descending/
// https://learn.microsoft.com/dotnet/api/system.linq.enumerable.thenby
// https://learn.microsoft.com/dotnet/api/system.linq.enumerable.thenbydescending
// [ThenBy] performs a subsequent ordering of the elements in a sequence in ascending order.
//
// [ThenBy]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.thenby
func ThenBy[Source cmp.Ordered](source *OrderedEnumerable[Source]) (*OrderedEnumerable[Source], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
return ThenByKey(source, Identity[Source])
}
// ThenByMust is like [ThenBy] but panics in case of error.
func ThenByMust[Source cmp.Ordered](source *OrderedEnumerable[Source]) *OrderedEnumerable[Source] {
return errorhelper.Must(ThenBy(source))
}
// [ThenByLs] performs a subsequent ordering of the elements in a sequence in ascending order using a specified lesser.
//
// [ThenByLs]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.thenby
func ThenByLs[Source any](source *OrderedEnumerable[Source], lesser collate.Lesser[Source]) (*OrderedEnumerable[Source], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if lesser == nil {
return nil, errorhelper.CallerError(ErrNilLesser)
}
return ThenByKeyLs(source, Identity[Source], lesser)
}
// ThenByLsMust is like [ThenByLs] but panics in case of error.
func ThenByLsMust[Source any](source *OrderedEnumerable[Source], lesser collate.Lesser[Source]) *OrderedEnumerable[Source] {
return errorhelper.Must(ThenByLs(source, lesser))
}
// [ThenByKey] performs a subsequent ordering of the elements in a sequence in ascending order according to a key.
//
// [ThenByKey]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.thenby
func ThenByKey[Source any, Key cmp.Ordered](source *OrderedEnumerable[Source],
keySelector func(Source) Key) (*OrderedEnumerable[Source], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
return ThenByKeyLs(source, keySelector, collate.Order[Key]{})
}
// ThenByKeyMust is like [ThenByKey] but panics in case of error.
func ThenByKeyMust[Source any, Key cmp.Ordered](source *OrderedEnumerable[Source],
keySelector func(Source) Key) *OrderedEnumerable[Source] {
return errorhelper.Must(ThenByKey(source, keySelector))
}
// [ThenByKeyLs] performs a subsequent ordering of the elements in a sequence
// in ascending order according to a key using a specified lesser.
//
// [ThenByKeyLs]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.thenby
func ThenByKeyLs[Source, Key any](source *OrderedEnumerable[Source],
keySelector func(Source) Key, lesser collate.Lesser[Key]) (*OrderedEnumerable[Source], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
if source.ls == nil || lesser == nil {
return nil, errorhelper.CallerError(ErrNilLesser)
}
return &OrderedEnumerable[Source]{
source.en,
compoundLesser(source.ls, projectionLesser(lesser, keySelector)),
},
nil
}
// ThenByKeyLsMust is like [ThenByKeyLs] but panics in case of error.
func ThenByKeyLsMust[Source, Key any](source *OrderedEnumerable[Source],
keySelector func(Source) Key, lesser collate.Lesser[Key]) *OrderedEnumerable[Source] {
return errorhelper.Must(ThenByKeyLs(source, keySelector, lesser))
}
// [ThenByDesc] performs a subsequent ordering of the elements in a sequence in descending order.
//
// [ThenByDesc]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.thenbydescending
func ThenByDesc[Source cmp.Ordered](source *OrderedEnumerable[Source]) (*OrderedEnumerable[Source], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
return ThenByDescKey(source, Identity[Source])
}
// ThenByDescMust is like [ThenByDesc] but panics in case of error.
func ThenByDescMust[Source cmp.Ordered](source *OrderedEnumerable[Source]) *OrderedEnumerable[Source] {
return errorhelper.Must(ThenByDesc(source))
}
// [ThenByDescLs] performs a subsequent ordering of the elements in a sequence in descending order using a specified lesser.
//
// [ThenByDescLs]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.thenbydescending
func ThenByDescLs[Source any](source *OrderedEnumerable[Source], lesser collate.Lesser[Source]) (*OrderedEnumerable[Source], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if lesser == nil {
return nil, errorhelper.CallerError(ErrNilLesser)
}
return ThenByDescKeyLs(source, Identity[Source], lesser)
}
// ThenByDescLsMust is like [ThenByDescLs] but panics in case of error.
func ThenByDescLsMust[Source any](source *OrderedEnumerable[Source], lesser collate.Lesser[Source]) *OrderedEnumerable[Source] {
return errorhelper.Must(ThenByDescLs(source, lesser))
}
// [ThenByDescKey] performs a subsequent ordering of the elements in a sequence in descending order according to a key.
//
// [ThenByDescKey]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.thenbydescending
func ThenByDescKey[Source any, Key cmp.Ordered](source *OrderedEnumerable[Source],
keySelector func(Source) Key) (*OrderedEnumerable[Source], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
return ThenByDescKeyLs(source, keySelector, collate.Order[Key]{})
}
// ThenByDescKeyMust is like [ThenByDescKey] but panics in case of error.
func ThenByDescKeyMust[Source any, Key cmp.Ordered](source *OrderedEnumerable[Source],
keySelector func(Source) Key) *OrderedEnumerable[Source] {
return errorhelper.Must(ThenByDescKey(source, keySelector))
}
// [ThenByDescKeyLs] performs a subsequent ordering of the elements in a sequence
// in descending order according to a key using a specified lesser.
//
// [ThenByDescKeyLs]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.thenbydescending
func ThenByDescKeyLs[Source, Key any](source *OrderedEnumerable[Source],
keySelector func(Source) Key, lesser collate.Lesser[Key]) (*OrderedEnumerable[Source], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
if source.ls == nil || lesser == nil {
return nil, errorhelper.CallerError(ErrNilLesser)
}
return &OrderedEnumerable[Source]{
source.en,
compoundLesser(source.ls, reverseLesser(projectionLesser(lesser, keySelector))),
},
nil
}
// ThenByDescKeyLsMust is like [ThenByDescKeyLs] but panics in case of error.
func ThenByDescKeyLsMust[Source, Key any](source *OrderedEnumerable[Source],
keySelector func(Source) Key, lesser collate.Lesser[Key]) *OrderedEnumerable[Source] {
return errorhelper.Must(ThenByDescKeyLs(source, keySelector, lesser))
}