-
Notifications
You must be signed in to change notification settings - Fork 0
/
map_iter.go
337 lines (307 loc) · 9.78 KB
/
map_iter.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
package g
import "iter"
// Pull converts the “push-style” iterator sequence seq
// into a “pull-style” iterator accessed by the two functions
// next and stop.
//
// Next returns the next pair in the sequence
// and a boolean indicating whether the pair is valid.
// When the sequence is over, next returns a pair of zero values and false.
// It is valid to call next after reaching the end of the sequence
// or after calling stop. These calls will continue
// to return a pair of zero values and false.
//
// Stop ends the iteration. It must be called when the caller is
// no longer interested in next values and next has not yet
// signaled that the sequence is over (with a false boolean return).
// It is valid to call stop multiple times and when next has
// already returned false.
//
// It is an error to call next or stop from multiple goroutines
// simultaneously.
func (seq SeqMap[K, V]) Pull() (func() (K, V, bool), func()) { return iter.Pull2(iter.Seq2[K, V](seq)) }
// Take returns a new iterator with the first n elements.
// The function creates a new iterator containing the first n elements from the original iterator.
func (seq SeqMap[K, V]) Take(n uint) SeqMap[K, V] { return takeMap(seq, n) }
// Keys returns an iterator containing all the keys in the ordered Map.
func (seq SeqMap[K, V]) Keys() SeqSlice[K] { return keysMap(seq) }
// Values returns an iterator containing all the values in the ordered Map.
func (seq SeqMap[K, V]) Values() SeqSlice[V] { return valuesMap(seq) }
// Chain creates a new iterator by concatenating the current iterator with other iterators.
//
// The function concatenates the key-value pairs from the current iterator with the key-value pairs from the provided iterators,
// producing a new iterator containing all concatenated elements.
//
// Params:
//
// - seqs ([]SeqMap[K, V]): Other iterators to be concatenated with the current iterator.
//
// Returns:
//
// - SeqMap[K, V]: A new iterator containing elements from the current iterator and the provided iterators.
//
// Example usage:
//
// iter1 := g.NewMap[int, string]().Set(1, "a").Iter()
// iter2 := g.NewMap[int, string]().Set(2, "b").Iter()
//
// // Concatenating iterators and collecting the result.
// iter1.Chain(iter2).Collect().Print()
//
// Output: Map{1:a, 2:b} // The output order may vary as Map is not ordered.
//
// The resulting iterator will contain elements from both iterators.
func (seq SeqMap[K, V]) Chain(seqs ...SeqMap[K, V]) SeqMap[K, V] {
return chainMap(append([]SeqMap[K, V]{seq}, seqs...)...)
}
// Count consumes the iterator, counting the number of iterations and returning it.
func (seq SeqMap[K, V]) Count() Int { return countMap(seq) }
// Collect collects all key-value pairs from the iterator and returns a Map.
func (seq SeqMap[K, V]) Collect() Map[K, V] {
collection := NewMap[K, V]()
seq(func(k K, v V) bool {
collection.Set(k, v)
return true
})
return collection
}
// Exclude returns a new iterator excluding elements that satisfy the provided function.
//
// This function creates a new iterator excluding key-value pairs for which the provided function returns true.
// It iterates through the current iterator, applying the function to each key-value pair.
// If the function returns true for a key-value pair, it will be excluded from the resulting iterator.
//
// Params:
//
// - fn (func(K, V) bool): The function applied to each key-value pair to determine exclusion.
//
// Returns:
//
// - SeqMap[K, V]: An iterator excluding elements that satisfy the given function.
//
// Example usage:
//
// m := g.NewMap[int, int]().
// Set(1, 1).
// Set(2, 2).
// Set(3, 3).
// Set(4, 4).
// Set(5, 5)
//
// notEven := m.Iter().
// Exclude(
// func(k, v int) bool {
// return v%2 == 0
// }).
// Collect()
// notEven.Print()
//
// Output: Map{1:1, 3:3, 5:5} // The output order may vary as Map is not ordered.
//
// The resulting iterator will exclude elements for which the function returns true.
func (seq SeqMap[K, V]) Exclude(fn func(K, V) bool) SeqMap[K, V] { return excludeMap(seq, fn) }
// Filter returns a new iterator containing only the elements that satisfy the provided function.
//
// This function creates a new iterator containing key-value pairs for which the provided function returns true.
// It iterates through the current iterator, applying the function to each key-value pair.
// If the function returns true for a key-value pair, it will be included in the resulting iterator.
//
// Params:
//
// - fn (func(K, V) bool): The function applied to each key-value pair to determine inclusion.
//
// Returns:
//
// - SeqMap[K, V]: An iterator containing elements that satisfy the given function.
//
// m := g.NewMap[int, int]().
// Set(1, 1).
// Set(2, 2).
// Set(3, 3).
// Set(4, 4).
// Set(5, 5)
//
// even := m.Iter().
// Filter(
// func(k, v int) bool {
// return v%2 == 0
// }).
// Collect()
// even.Print()
//
// Output: Map{2:2, 4:4} // The output order may vary as Map is not ordered.
//
// The resulting iterator will contain elements for which the function returns true.
func (seq SeqMap[K, V]) Filter(fn func(K, V) bool) SeqMap[K, V] { return filterMap(seq, fn) }
// The resulting Option may contain the first element that satisfies the condition, or None if not found.
func (seq SeqMap[K, V]) Find(fn func(k K, v V) bool) Option[Pair[K, V]] { return findMap(seq, fn) }
// ForEach iterates through all elements and applies the given function to each key-value pair.
//
// This function traverses the entire iterator and applies the provided function to each key-value pair.
// It iterates through the current iterator, executing the function on each key-value pair.
//
// Params:
//
// - fn (func(K, V)): The function to be applied to each key-value pair in the iterator.
//
// Example usage:
//
// m := g.NewMap[int, int]().
// Set(1, 1).
// Set(2, 2).
// Set(3, 3).
// Set(4, 4).
// Set(5, 5)
//
// mmap := m.Iter().
// Map(
// func(k, v int) (int, int) {
// return k * k, v * v
// }).
// Collect()
//
// mmap.Print()
//
// Output: Map{1:1, 4:4, 9:9, 16:16, 25:25} // The output order may vary as Map is not ordered.
//
// The function fn will be executed for each key-value pair in the iterator.
func (seq SeqMap[K, V]) ForEach(fn func(k K, v V)) {
seq(func(k K, v V) bool {
fn(k, v)
return true
})
}
// Inspect creates a new iterator that wraps around the current iterator
// and allows inspecting each key-value pair as it passes through.
func (seq SeqMap[K, V]) Inspect(fn func(k K, v V)) SeqMap[K, V] { return inspectMap(seq, fn) }
// Map creates a new iterator by applying the given function to each key-value pair.
//
// This function generates a new iterator by traversing the current iterator and applying the provided
// function to each key-value pair. It transforms the key-value pairs according to the given function.
//
// Params:
//
// - fn (func(K, V) (K, V)): The function to be applied to each key-value pair in the iterator.
// It takes a key-value pair and returns a new transformed key-value pair.
//
// Returns:
//
// - SeqMap[K, V]: A new iterator containing key-value pairs transformed by the provided function.
//
// Example usage:
//
// m := g.NewMap[int, int]().
// Set(1, 1).
// Set(2, 2).
// Set(3, 3).
// Set(4, 4).
// Set(5, 5)
//
// mmap := m.Iter().
// Map(
// func(k, v int) (int, int) {
// return k * k, v * v
// }).
// Collect()
//
// mmap.Print()
//
// Output: Map{1:1, 4:4, 9:9, 16:16, 25:25} // The output order may vary as Map is not ordered.
//
// The resulting iterator will contain key-value pairs transformed by the given function.
func (seq SeqMap[K, V]) Map(transform func(K, V) (K, V)) SeqMap[K, V] { return mapMap(seq, transform) }
// The iteration will stop when the provided function returns false for an element.
func (seq SeqMap[K, V]) Range(fn func(k K, v V) bool) {
seq(func(k K, v V) bool {
return fn(k, v)
})
}
func ToSeqMap[K comparable, V any](hashmap map[K]V) SeqMap[K, V] {
return func(yield func(K, V) bool) {
for k, v := range hashmap {
if !yield(k, v) {
return
}
}
}
}
func chainMap[K comparable, V any](seqs ...SeqMap[K, V]) SeqMap[K, V] {
return func(yield func(K, V) bool) {
for _, seq := range seqs {
seq(func(k K, v V) bool {
return yield(k, v)
})
}
}
}
func mapMap[K comparable, V any](seq SeqMap[K, V], fn func(K, V) (K, V)) SeqMap[K, V] {
return func(yield func(K, V) bool) {
seq(func(k K, v V) bool {
return yield(fn(k, v))
})
}
}
func filterMap[K comparable, V any](seq SeqMap[K, V], fn func(K, V) bool) SeqMap[K, V] {
return func(yield func(K, V) bool) {
seq(func(k K, v V) bool {
if fn(k, v) {
return yield(k, v)
}
return true
})
}
}
func excludeMap[K comparable, V any](s SeqMap[K, V], fn func(K, V) bool) SeqMap[K, V] {
return filterMap(s, func(k K, v V) bool { return !fn(k, v) })
}
func inspectMap[K comparable, V any](seq SeqMap[K, V], fn func(K, V)) SeqMap[K, V] {
return func(yield func(K, V) bool) {
seq(func(k K, v V) bool {
fn(k, v)
return yield(k, v)
})
}
}
func keysMap[K comparable, V any](seq SeqMap[K, V]) SeqSlice[K] {
return func(yield func(K) bool) {
seq(func(k K, _ V) bool {
return yield(k)
})
}
}
func valuesMap[K comparable, V any](seq SeqMap[K, V]) SeqSlice[V] {
return func(yield func(V) bool) {
seq(func(_ K, v V) bool {
return yield(v)
})
}
}
func findMap[K comparable, V any](seq SeqMap[K, V], fn func(K, V) bool) (r Option[Pair[K, V]]) {
seq(func(k K, v V) bool {
if !fn(k, v) {
return true
}
r = Some(Pair[K, V]{k, v})
return false
})
return r
}
func takeMap[K comparable, V any](seq SeqMap[K, V], n uint) SeqMap[K, V] {
return func(yield func(K, V) bool) {
seq(func(k K, v V) bool {
if n == 0 {
return false
}
n--
return yield(k, v)
})
}
}
func countMap[K comparable, V any](seq SeqMap[K, V]) Int {
var counter Int
seq(func(K, V) bool {
counter++
return true
})
return counter
}