github.com/enetx/g@v1.0.80/map_ordered_iter.go (about) 1 package g 2 3 import ( 4 "context" 5 "iter" 6 7 "github.com/enetx/g/cmp" 8 ) 9 10 // Pull converts the “push-style” iterator sequence seq 11 // into a “pull-style” iterator accessed by the two functions 12 // next and stop. 13 // 14 // Next returns the next pair in the sequence 15 // and a boolean indicating whether the pair is valid. 16 // When the sequence is over, next returns a pair of zero values and false. 17 // It is valid to call next after reaching the end of the sequence 18 // or after calling stop. These calls will continue 19 // to return a pair of zero values and false. 20 // 21 // Stop ends the iteration. It must be called when the caller is 22 // no longer interested in next values and next has not yet 23 // signaled that the sequence is over (with a false boolean return). 24 // It is valid to call stop multiple times and when next has 25 // already returned false. 26 // 27 // It is an error to call next or stop from multiple goroutines 28 // simultaneously. 29 func (seq SeqMapOrd[K, V]) Pull() (func() (K, V, bool), func()) { 30 return iter.Pull2(iter.Seq2[K, V](seq)) 31 } 32 33 // Keys returns an iterator containing all the keys in the ordered Map. 34 func (seq SeqMapOrd[K, V]) Keys() SeqSlice[K] { return keysMapOrd(seq) } 35 36 // Values returns an iterator containing all the values in the ordered Map. 37 func (seq SeqMapOrd[K, V]) Values() SeqSlice[V] { return valuesMapOrd(seq) } 38 39 // Unzip returns a tuple of slices containing keys and values from the ordered map. 40 func (seq SeqMapOrd[K, V]) Unzip() (SeqSlice[K], SeqSlice[V]) { return seq.Keys(), seq.Values() } 41 42 // SortBy applies a custom sorting function to the elements in the iterator 43 // and returns a new iterator containing the sorted elements. 44 // 45 // The sorting function 'fn' should take two arguments, 'a' and 'b', of type Pair[K, V], 46 // and return true if 'a' should be ordered before 'b', and false otherwise. 47 // 48 // Example: 49 // 50 // m := g.NewMapOrd[g.Int, g.String]() 51 // m. 52 // Set(6, "bb"). 53 // Set(0, "dd"). 54 // Set(1, "aa"). 55 // Set(5, "xx"). 56 // Set(2, "cc"). 57 // Set(3, "ff"). 58 // Set(4, "zz"). 59 // Iter(). 60 // SortBy( 61 // func(a, b g.Pair[g.Int, g.String]) cmp.Ordering { 62 // return a.Key.Cmp(b.Key) 63 // // return a.Value.Cmp(b.Value) 64 // }). 65 // Collect(). 66 // Print() 67 // 68 // Output: MapOrd{0:dd, 1:aa, 2:cc, 3:ff, 4:zz, 5:xx, 6:bb} 69 // 70 // The returned iterator is of type SeqMapOrd[K, V], which implements the iterator 71 // interface for further iteration over the sorted elements. 72 func (seq SeqMapOrd[K, V]) SortBy(fn func(a, b Pair[K, V]) cmp.Ordering) SeqMapOrd[K, V] { 73 return sortByMapOrd(seq, fn) 74 } 75 76 // SortByKey applies a custom sorting function to the keys in the iterator 77 // and returns a new iterator containing the sorted elements. 78 // 79 // The sorting function 'fn' should take two arguments, 'a' and 'b', of type K, 80 // and return true if 'a' should be ordered before 'b', and false otherwise. 81 // 82 // Example: 83 // 84 // m := g.NewMapOrd[g.Int, g.String]() 85 // m. 86 // Set(6, "bb"). 87 // Set(0, "dd"). 88 // Set(1, "aa"). 89 // Set(5, "xx"). 90 // Set(2, "cc"). 91 // Set(3, "ff"). 92 // Set(4, "zz"). 93 // Iter(). 94 // SortByKey(g.Int.Cmp). 95 // Collect(). 96 // Print() 97 // 98 // Output: MapOrd{0:dd, 1:aa, 2:cc, 3:ff, 4:zz, 5:xx, 6:bb} 99 func (seq SeqMapOrd[K, V]) SortByKey(fn func(a, b K) cmp.Ordering) SeqMapOrd[K, V] { 100 return sortByKeyMapOrd(seq, fn) 101 } 102 103 // SortByValue applies a custom sorting function to the values in the iterator 104 // and returns a new iterator containing the sorted elements. 105 // 106 // The sorting function 'fn' should take two arguments, 'a' and 'b', of type V, 107 // and return true if 'a' should be ordered before 'b', and false otherwise. 108 // 109 // Example: 110 // 111 // m := g.NewMapOrd[g.Int, g.String]() 112 // m. 113 // Set(6, "bb"). 114 // Set(0, "dd"). 115 // Set(1, "aa"). 116 // Set(5, "xx"). 117 // Set(2, "cc"). 118 // Set(3, "ff"). 119 // Set(4, "zz"). 120 // Iter(). 121 // SortByValue(g.String.Cmp). 122 // Collect(). 123 // Print() 124 // 125 // Output: MapOrd{1:aa, 6:bb, 2:cc, 0:dd, 3:ff, 5:xx, 4:zz} 126 func (seq SeqMapOrd[K, V]) SortByValue(fn func(a, b V) cmp.Ordering) SeqMapOrd[K, V] { 127 return sortByValueMapOrd(seq, fn) 128 } 129 130 // Inspect creates a new iterator that wraps around the current iterator 131 // and allows inspecting each key-value pair as it passes through. 132 func (seq SeqMapOrd[K, V]) Inspect(fn func(k K, v V)) SeqMapOrd[K, V] { return inspectMapOrd(seq, fn) } 133 134 // StepBy creates a new iterator that iterates over every N-th element of the original iterator. 135 // This function is useful when you want to skip a specific number of elements between each iteration. 136 // 137 // Parameters: 138 // - n int: The step size, indicating how many elements to skip between each iteration. 139 // 140 // Returns: 141 // - SeqMapOrd[K, V]: A new iterator that produces key-value pairs from the original iterator with a step size of N. 142 // 143 // Example usage: 144 // 145 // mapIter := g.MapOrd[string, int]{{"one", 1}, {"two", 2}, {"three", 3}}.Iter() 146 // iter := mapIter.StepBy(2) 147 // result := iter.Collect() 148 // result.Print() 149 // 150 // Output: MapOrd{one:1, three:3} 151 // 152 // The resulting iterator will produce key-value pairs from the original iterator with a step size of N. 153 func (seq SeqMapOrd[K, V]) StepBy(n uint) SeqMapOrd[K, V] { return stepbyMapOrd(seq, n) } 154 155 // Chain concatenates the current iterator with other iterators, returning a new iterator. 156 // 157 // The function creates a new iterator that combines the elements of the current iterator 158 // with elements from the provided iterators in the order they are given. 159 // 160 // Params: 161 // 162 // - seqs ([]seqMapOrd[K, V]): Other iterators to be concatenated with the current iterator. 163 // 164 // Returns: 165 // 166 // - SeqMapOrd[K, V]: A new iterator containing elements from the current iterator and the provided iterators. 167 // 168 // Example usage: 169 // 170 // iter1 := g.NewMapOrd[int, string]() 171 // iter1.Set(1, "a").Iter() 172 // 173 // iter2 := g.NewMapOrd[int, string]() 174 // iter2.Set(2, "b").Iter() 175 // 176 // // Concatenating iterators and collecting the result. 177 // iter1.Chain(iter2).Collect().Print() 178 // 179 // Output: MapOrd{1:a, 2:b} 180 // 181 // The resulting iterator will contain elements from both iterators in the specified order. 182 func (seq SeqMapOrd[K, V]) Chain(seqs ...SeqMapOrd[K, V]) SeqMapOrd[K, V] { 183 return chainMapOrd(append([]SeqMapOrd[K, V]{seq}, seqs...)...) 184 } 185 186 // Count consumes the iterator, counting the number of iterations and returning it. 187 func (seq SeqMapOrd[K, V]) Count() Int { return countMapOrd(seq) } 188 189 // Collect collects all key-value pairs from the iterator and returns a MapOrd. 190 func (seq SeqMapOrd[K, V]) Collect() MapOrd[K, V] { 191 collection := NewMapOrd[K, V]() 192 193 seq(func(k K, v V) bool { 194 collection.Set(k, v) 195 return true 196 }) 197 198 return collection 199 } 200 201 // Skip returns a new iterator skipping the first n elements. 202 // 203 // The function creates a new iterator that skips the first n elements of the current iterator 204 // and returns an iterator starting from the (n+1)th element. 205 // 206 // Params: 207 // 208 // - n (uint): The number of elements to skip from the beginning of the iterator. 209 // 210 // Returns: 211 // 212 // - SeqMapOrd[K, V]: An iterator that starts after skipping the first n elements. 213 // 214 // Example usage: 215 // 216 217 // iter := g.NewMapOrd[int, string]() 218 // iter. 219 // Set(1, "a"). 220 // Set(2, "b"). 221 // Set(3, "c"). 222 // Set(4, "d"). 223 // Iter() 224 // 225 // // Skipping the first two elements and collecting the rest. 226 // iter.Skip(2).Collect().Print() 227 // 228 // Output: MapOrd{3:c, 4:d} 229 // 230 // The resulting iterator will start after skipping the specified number of elements. 231 func (seq SeqMapOrd[K, V]) Skip(n uint) SeqMapOrd[K, V] { return skipMapOrd(seq, n) } 232 233 // Exclude returns a new iterator excluding elements that satisfy the provided function. 234 // 235 // The function creates a new iterator excluding elements from the current iterator 236 // for which the provided function returns true. 237 // 238 // Params: 239 // 240 // - fn (func(K, V) bool): The function used to determine exclusion criteria for elements. 241 // 242 // Returns: 243 // 244 // - SeqMapOrd[K, V]: A new iterator excluding elements that satisfy the given condition. 245 // 246 // Example usage: 247 // 248 // mo := g.NewMapOrd[int, int]() 249 // mo. 250 // Set(1, 1). 251 // Set(2, 2). 252 // Set(3, 3). 253 // Set(4, 4). 254 // Set(5, 5) 255 // 256 // notEven := mo.Iter(). 257 // Exclude( 258 // func(k, v int) bool { 259 // return v%2 == 0 260 // }). 261 // Collect() 262 // notEven.Print() 263 // 264 // Output: MapOrd{1:1, 3:3, 5:5} 265 // 266 // The resulting iterator will exclude elements based on the provided condition. 267 func (seq SeqMapOrd[K, V]) Exclude(fn func(K, V) bool) SeqMapOrd[K, V] { return excludeMapOrd(seq, fn) } 268 269 // Filter returns a new iterator containing only the elements that satisfy the provided function. 270 // 271 // The function creates a new iterator including elements from the current iterator 272 // for which the provided function returns true. 273 // 274 // Params: 275 // 276 // - fn (func(K, V) bool): The function used to determine inclusion criteria for elements. 277 // 278 // Returns: 279 // 280 // - SeqMapOrd[K, V]: A new iterator containing elements that satisfy the given condition. 281 // 282 // Example usage: 283 // 284 // mo := g.NewMapOrd[int, int]() 285 // mo. 286 // Set(1, 1). 287 // Set(2, 2). 288 // Set(3, 3). 289 // Set(4, 4). 290 // Set(5, 5) 291 // 292 // even := mo.Iter(). 293 // Filter( 294 // func(k, v int) bool { 295 // return v%2 == 0 296 // }). 297 // Collect() 298 // even.Print() 299 // 300 // Output: MapOrd{2:2, 4:4} 301 // 302 // The resulting iterator will include elements based on the provided condition. 303 func (seq SeqMapOrd[K, V]) Filter(fn func(K, V) bool) SeqMapOrd[K, V] { return filterMapOrd(seq, fn) } 304 305 // The resulting Option may contain the first element that satisfies the condition, or None if not found. 306 func (seq SeqMapOrd[K, V]) Find(fn func(k K, v V) bool) Option[Pair[K, V]] { 307 return findMapOrd(seq, fn) 308 } 309 310 // ForEach iterates through all elements and applies the given function to each key-value pair. 311 // 312 // The function applies the provided function to each key-value pair in the iterator. 313 // 314 // Params: 315 // 316 // - fn (func(K, V)): The function to be applied to each key-value pair in the iterator. 317 // 318 // Example usage: 319 // 320 // iter := g.NewMapOrd[int, int]() 321 // iter. 322 // Set(1, 1). 323 // Set(2, 2). 324 // Set(3, 3). 325 // Set(4, 4). 326 // Set(5, 5). 327 // Iter() 328 // 329 // iter.ForEach(func(key K, val V) { 330 // // Process key-value pair 331 // }) 332 // 333 // The provided function will be applied to each key-value pair in the iterator. 334 func (seq SeqMapOrd[K, V]) ForEach(fn func(k K, v V)) { 335 seq(func(k K, v V) bool { 336 fn(k, v) 337 return true 338 }) 339 } 340 341 // Map creates a new iterator by applying the given function to each key-value pair. 342 // 343 // The function creates a new iterator by applying the provided function to each key-value pair in the iterator. 344 // 345 // Params: 346 // 347 // - fn (func(K, V) (K, V)): The function used to transform each key-value pair in the iterator. 348 // 349 // Returns: 350 // 351 // - SeqMapOrd[K, V]: A new iterator containing transformed key-value pairs. 352 // 353 // Example usage: 354 // 355 // mo := g.NewMapOrd[int, int]() 356 // mo. 357 // Set(1, 1). 358 // Set(2, 2). 359 // Set(3, 3). 360 // Set(4, 4). 361 // Set(5, 5) 362 // 363 // momap := mo.Iter(). 364 // Map( 365 // func(k, v int) (int, int) { 366 // return k * k, v * v 367 // }). 368 // Collect() 369 // 370 // momap.Print() 371 // 372 // Output: MapOrd{1:1, 4:4, 9:9, 16:16, 25:25} 373 // 374 // The resulting iterator will contain transformed key-value pairs. 375 func (seq SeqMapOrd[K, V]) Map(transform func(K, V) (K, V)) SeqMapOrd[K, V] { 376 return mapiMapOrd(seq, transform) 377 } 378 379 // Range iterates through elements until the given function returns false. 380 // 381 // The function iterates through the key-value pairs in the iterator, applying the provided function to each pair. 382 // It continues iterating until the function returns false. 383 // 384 // Params: 385 // 386 // - fn (func(K, V) bool): The function to be applied to each key-value pair in the iterator. 387 // 388 // Example usage: 389 // 390 // iter := g.NewMapOrd[int, int]() 391 // iter. 392 // Set(1, 1). 393 // Set(2, 2). 394 // Set(3, 3). 395 // Set(4, 4). 396 // Set(5, 5). 397 // Iter() 398 // 399 // iter.Range(func(k, v int) bool { 400 // fmt.Println(v) // Replace this with the function logic you need. 401 // return v < 5 // Replace this with the condition for continuing iteration. 402 // }) 403 // 404 // The iteration will stop when the provided function returns false. 405 func (seq SeqMapOrd[K, V]) Range(fn func(k K, v V) bool) { 406 seq(func(k K, v V) bool { 407 return fn(k, v) 408 }) 409 } 410 411 // Take returns a new iterator with the first n elements. 412 // The function creates a new iterator containing the first n elements from the original iterator. 413 func (seq SeqMapOrd[K, V]) Take(limit uint) SeqMapOrd[K, V] { return takeMapOrd(seq, limit) } 414 415 // ToChan converts the iterator into a channel, optionally with context(s). 416 // 417 // The function converts the key-value pairs from the iterator into a channel, allowing iterative processing 418 // using channels. It can be used to stream key-value pairs for concurrent or asynchronous operations. 419 // 420 // Params: 421 // 422 // - ctxs (...context.Context): Optional context(s) that can be used to cancel or set deadlines for the operation. 423 // 424 // Returns: 425 // 426 // - chan Pair[K, V]: A channel emitting key-value pairs from the iterator. 427 // 428 // Example usage: 429 // 430 // iter := g.NewMapOrd[int, int]() 431 // iter. 432 // Set(1, 1). 433 // Set(2, 2). 434 // Set(3, 3). 435 // Set(4, 4). 436 // Set(5, 5). 437 // Iter() 438 // 439 // ctx, cancel := context.WithCancel(context.Background()) 440 // defer cancel() // Ensure cancellation to avoid goroutine leaks. 441 // 442 // ch := iter.ToChan(ctx) 443 // for pair := range ch { 444 // // Process key-value pair from the channel 445 // } 446 // 447 // The function converts the iterator into a channel to allow sequential or concurrent processing of key-value pairs. 448 func (seq SeqMapOrd[K, V]) ToChan(ctxs ...context.Context) chan Pair[K, V] { 449 ch := make(chan Pair[K, V]) 450 451 ctx := context.Background() 452 if len(ctxs) != 0 { 453 ctx = ctxs[0] 454 } 455 456 go func() { 457 defer close(ch) 458 459 for k, v := range seq { 460 select { 461 case <-ctx.Done(): 462 return 463 default: 464 ch <- Pair[K, V]{k, v} 465 } 466 } 467 }() 468 469 return ch 470 } 471 472 func ToSeqMapOrd[K, V any](mo MapOrd[K, V]) SeqMapOrd[K, V] { 473 return func(yield func(K, V) bool) { 474 for _, v := range mo { 475 if !yield(v.Key, v.Value) { 476 return 477 } 478 } 479 } 480 } 481 482 func sortByMapOrd[K, V any](seq SeqMapOrd[K, V], fn func(a, b Pair[K, V]) cmp.Ordering) SeqMapOrd[K, V] { 483 items := seq.Collect() 484 items.SortBy(fn) 485 486 return items.Iter() 487 } 488 489 func sortByKeyMapOrd[K, V any](seq SeqMapOrd[K, V], fn func(a, b K) cmp.Ordering) SeqMapOrd[K, V] { 490 items := seq.Collect() 491 items.SortByKey(fn) 492 493 return items.Iter() 494 } 495 496 func sortByValueMapOrd[K, V any](seq SeqMapOrd[K, V], fn func(a, b V) cmp.Ordering) SeqMapOrd[K, V] { 497 items := seq.Collect() 498 items.SortByValue(fn) 499 500 return items.Iter() 501 } 502 503 func inspectMapOrd[K, V any](seq SeqMapOrd[K, V], fn func(K, V)) SeqMapOrd[K, V] { 504 return func(yield func(K, V) bool) { 505 seq(func(k K, v V) bool { 506 fn(k, v) 507 return yield(k, v) 508 }) 509 } 510 } 511 512 func stepbyMapOrd[K, V any](seq SeqMapOrd[K, V], n uint) SeqMapOrd[K, V] { 513 return func(yield func(K, V) bool) { 514 i := uint(0) 515 seq(func(k K, v V) bool { 516 i++ 517 if (i-1)%n == 0 { 518 return yield(k, v) 519 } 520 521 return true 522 }) 523 } 524 } 525 526 func chainMapOrd[K, V any](seqs ...SeqMapOrd[K, V]) SeqMapOrd[K, V] { 527 return func(yield func(K, V) bool) { 528 for _, seq := range seqs { 529 seq(func(k K, v V) bool { 530 return yield(k, v) 531 }) 532 } 533 } 534 } 535 536 func skipMapOrd[K, V any](seq SeqMapOrd[K, V], n uint) SeqMapOrd[K, V] { 537 return func(yield func(K, V) bool) { 538 seq(func(k K, v V) bool { 539 if n > 0 { 540 n-- 541 return true 542 } 543 return yield(k, v) 544 }) 545 } 546 } 547 548 func mapiMapOrd[K, V any](seq SeqMapOrd[K, V], fn func(K, V) (K, V)) SeqMapOrd[K, V] { 549 return func(yield func(K, V) bool) { 550 seq(func(k K, v V) bool { 551 return yield(fn(k, v)) 552 }) 553 } 554 } 555 556 func filterMapOrd[K, V any](seq SeqMapOrd[K, V], fn func(K, V) bool) SeqMapOrd[K, V] { 557 return func(yield func(K, V) bool) { 558 seq(func(k K, v V) bool { 559 if fn(k, v) { 560 return yield(k, v) 561 } 562 return true 563 }) 564 } 565 } 566 567 func excludeMapOrd[K, V any](seq SeqMapOrd[K, V], fn func(K, V) bool) SeqMapOrd[K, V] { 568 return filterMapOrd(seq, func(k K, v V) bool { return !fn(k, v) }) 569 } 570 571 func takeMapOrd[K, V any](seq SeqMapOrd[K, V], n uint) SeqMapOrd[K, V] { 572 return func(yield func(K, V) bool) { 573 seq(func(k K, v V) bool { 574 if n == 0 { 575 return false 576 } 577 n-- 578 return yield(k, v) 579 }) 580 } 581 } 582 583 func keysMapOrd[K, V any](seq SeqMapOrd[K, V]) SeqSlice[K] { 584 return func(yield func(K) bool) { 585 seq(func(k K, _ V) bool { 586 return yield(k) 587 }) 588 } 589 } 590 591 func valuesMapOrd[K, V any](seq SeqMapOrd[K, V]) SeqSlice[V] { 592 return func(yield func(V) bool) { 593 seq(func(_ K, v V) bool { 594 return yield(v) 595 }) 596 } 597 } 598 599 func findMapOrd[K, V any](seq SeqMapOrd[K, V], fn func(K, V) bool) (r Option[Pair[K, V]]) { 600 seq(func(k K, v V) bool { 601 if !fn(k, v) { 602 return true 603 } 604 r = Some(Pair[K, V]{k, v}) 605 return false 606 }) 607 608 return r 609 } 610 611 func countMapOrd[K, V any](seq SeqMapOrd[K, V]) Int { 612 var counter Int 613 seq(func(K, V) bool { 614 counter++ 615 return true 616 }) 617 618 return counter 619 }