-
Notifications
You must be signed in to change notification settings - Fork 6
/
orderbykey.go
92 lines (85 loc) · 2.9 KB
/
orderbykey.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
package go2linq
import (
"cmp"
"iter"
"slices"
"sort"
"github.com/solsw/errorhelper"
)
func orderByKeyLsPrim[Source, Key any](source iter.Seq[Source],
keySelector func(Source) Key, less func(Key, Key) bool) iter.Seq[Source] {
type sk struct {
s Source
k Key
}
var sksk []sk
for s := range source {
sksk = append(sksk, sk{s: s, k: keySelector(s)})
}
sort.SliceStable(sksk, func(i, j int) bool {
return less(sksk[i].k, sksk[j].k)
})
ss := make([]Source, len(sksk))
for i := range len(sksk) {
ss[i] = sksk[i].s
}
return slices.Values(ss)
}
// [OrderByKey] sorts the elements of a sequence in ascending order according to a key.
//
// [OrderByKey]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.orderby
func OrderByKey[Source any, Key cmp.Ordered](source iter.Seq[Source],
keySelector func(Source) Key) (iter.Seq[Source], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
return orderByKeyLsPrim(source, keySelector, cmp.Less), nil
}
// [OrderByKeyLs] sorts the elements of a sequence in ascending order of keys using a specified 'less' function.
//
// [OrderByKeyLs]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.orderby
func OrderByKeyLs[Source, Key any](source iter.Seq[Source],
keySelector func(Source) Key, less func(Key, Key) bool) (iter.Seq[Source], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
if less == nil {
return nil, errorhelper.CallerError(ErrNilLess)
}
return orderByKeyLsPrim(source, keySelector, less), nil
}
// [OrderByKeyDesc] sorts the elements of a sequence in descending order according to a key.
//
// [OrderByKeyDesc]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.orderbydescending
func OrderByKeyDesc[Source any, Key cmp.Ordered](source iter.Seq[Source],
keySelector func(Source) Key) (iter.Seq[Source], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
return orderByKeyLsPrim(source, keySelector, ReverseLess[Key](cmp.Less)), nil
}
// [OrderByKeyDescLs] sorts the elements of a sequence in descending order of keys using a 'less' function.
//
// [OrderByKeyDescLs]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.orderbydescending
func OrderByKeyDescLs[Source, Key any](source iter.Seq[Source],
keySelector func(Source) Key, less func(Key, Key) bool) (iter.Seq[Source], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
if less == nil {
return nil, errorhelper.CallerError(ErrNilLess)
}
return orderByKeyLsPrim(source, keySelector, ReverseLess[Key](less)), nil
}