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  }