-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathgroupby.go
160 lines (150 loc) · 6.97 KB
/
groupby.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
package go2linq
import (
"iter"
"slices"
"github.com/solsw/errorhelper"
"github.com/solsw/generichelper"
)
// [GroupBy] groups the elements of a sequence according to a specified key selector function.
// The keys are compared using [generichelper.DeepEqual]. 'source' is enumerated immediately.
//
// [GroupBy]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.groupby
func GroupBy[Source, Key any](source iter.Seq[Source], keySelector func(Source) Key) (iter.Seq[Grouping[Key, Source]], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
r, _ := GroupBySelEq(source, keySelector, Identity[Source], generichelper.DeepEqual[Key])
return r, nil
}
// [GroupByEq] groups the elements of a sequence according to a specified key
// selector function and compares the keys using 'keyEqual'. 'source' is enumerated immediately.
//
// [GroupByEq]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.groupby
func GroupByEq[Source, Key any](source iter.Seq[Source], keySelector func(Source) Key,
keyEqual func(Key, Key) bool) (iter.Seq[Grouping[Key, Source]], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
if keyEqual == nil {
return nil, errorhelper.CallerError(ErrNilEqual)
}
r, _ := GroupBySelEq(source, keySelector, Identity[Source], keyEqual)
return r, nil
}
// [GroupBySel] groups the elements of a sequence according to a specified key selector function
// and projects the elements for each group using a specified function.
// The keys are compared using [generichelper.DeepEqual]. 'source' is enumerated immediately.
//
// [GroupBySel]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.groupby
func GroupBySel[Source, Key, Element any](source iter.Seq[Source], keySelector func(Source) Key,
elementSelector func(Source) Element) (iter.Seq[Grouping[Key, Element]], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil || elementSelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
r, _ := GroupBySelEq(source, keySelector, elementSelector, generichelper.DeepEqual[Key])
return r, nil
}
// [GroupBySelEq] groups the elements of a sequence according to a key selector function.
// The keys are compared using 'keyEqual' and each group's elements are projected using a specified function.
// 'source' is enumerated immediately.
//
// [GroupBySelEq]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.groupby
func GroupBySelEq[Source, Key, Element any](source iter.Seq[Source], keySelector func(Source) Key,
elementSelector func(Source) Element, keyEqual func(Key, Key) bool) (iter.Seq[Grouping[Key, Element]], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil || elementSelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
if keyEqual == nil {
return nil, errorhelper.CallerError(ErrNilEqual)
}
lk, _ := ToLookupSelEq(source, keySelector, elementSelector, keyEqual)
return slices.Values(lk.groupings), nil
}
// [GroupByRes] groups the elements of a sequence according to a specified key selector function
// and creates a result value from each group and its key.
// The keys are compared using [generichelper.DeepEqual]. 'source' is enumerated immediately.
//
// [GroupByRes]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.groupby
func GroupByRes[Source, Key, Result any](source iter.Seq[Source], keySelector func(Source) Key,
resultSelector func(Key, iter.Seq[Source]) Result) (iter.Seq[Result], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil || resultSelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
r, _ := GroupBySelResEq(source, keySelector, Identity[Source], resultSelector, generichelper.DeepEqual[Key])
return r, nil
}
// [GroupByResEq] groups the elements of a sequence according to a specified key selector function
// and creates a result value from each group and its key.
// The keys are compared using 'keyEqual'. 'source' is enumerated immediately.
//
// [GroupByResEq]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.groupby
func GroupByResEq[Source, Key, Result any](source iter.Seq[Source], keySelector func(Source) Key,
resultSelector func(Key, iter.Seq[Source]) Result, keyEqual func(Key, Key) bool) (iter.Seq[Result], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil || resultSelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
if keyEqual == nil {
return nil, errorhelper.CallerError(ErrNilEqual)
}
r, _ := GroupBySelResEq(source, keySelector, Identity[Source], resultSelector, keyEqual)
return r, nil
}
// [GroupBySelRes] groups the elements of a sequence according to a specified
// key selector function and creates a result value from each group and its key.
// The elements of each group are projected using a specified function.
// Key values are compared using [generichelper.DeepEqual]. 'source' is enumerated immediately.
//
// [GroupBySelRes]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.groupby
func GroupBySelRes[Source, Key, Element, Result any](source iter.Seq[Source], keySelector func(Source) Key,
elementSelector func(Source) Element, resultSelector func(Key, iter.Seq[Element]) Result) (iter.Seq[Result], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil || elementSelector == nil || resultSelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
r, _ := GroupBySelResEq(source, keySelector, elementSelector, resultSelector, generichelper.DeepEqual[Key])
return r, nil
}
// [GroupBySelResEq] groups the elements of a sequence according to a specified key selector function
// and creates a result value from each group and its key.
// Key values are compared using 'keyEqual' and the elements of each group are projected using a specified function.
// 'source' is enumerated immediately.
//
// [GroupBySelResEq]: https://learn.microsoft.com/dotnet/api/system.linq.enumerable.groupby
func GroupBySelResEq[Source, Key, Element, Result any](source iter.Seq[Source], keySelector func(Source) Key,
elementSelector func(Source) Element, resultSelector func(Key, iter.Seq[Element]) Result,
keyEqual func(Key, Key) bool) (iter.Seq[Result], error) {
if source == nil {
return nil, errorhelper.CallerError(ErrNilSource)
}
if keySelector == nil || elementSelector == nil || resultSelector == nil {
return nil, errorhelper.CallerError(ErrNilSelector)
}
if keyEqual == nil {
return nil, errorhelper.CallerError(ErrNilEqual)
}
gg, _ := GroupBySelEq(source, keySelector, elementSelector, keyEqual)
r, _ := Select(gg, func(g Grouping[Key, Element]) Result {
return resultSelector(g.key, g.Values())
})
return r, nil
}