Files
phishingclub/backend/vendor/github.com/enetx/g/map_iter.go
T
Ronni Skansing 07c8adaf76 update vendor deps
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
2025-11-06 23:31:08 +01:00

383 lines
12 KiB
Go

package g
import (
"context"
"runtime"
"github.com/enetx/iter"
)
// IterPar parallelizes the SeqMap using the specified number of workers.
func (seq SeqMap[K, V]) Parallel(workers ...Int) SeqMapPar[K, V] {
numCPU := Int(runtime.NumCPU())
count := Slice[Int](workers).Get(0).UnwrapOr(numCPU)
if count.Lte(0) {
count = numCPU
}
return SeqMapPar[K, V]{
seq: seq,
workers: count,
process: func(p Pair[K, V]) (Pair[K, V], bool) { return p, true },
}
}
// 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 SeqMap[K, V](iter.Take2(iter.Seq2[K, V](seq), int(n)))
}
// Nth returns the nth key-value pair (0-indexed) in the sequence.
func (seq SeqMap[K, V]) Nth(n Int) Option[Pair[K, V]] {
key, value, found := iter.Nth2(iter.Seq2[K, V](seq), int(n))
if found {
return Some(Pair[K, V]{Key: key, Value: value})
}
return None[Pair[K, V]]()
}
// Keys returns an iterator containing all the keys in the ordered Map.
func (seq SeqMap[K, V]) Keys() SeqSlice[K] {
return SeqSlice[K](iter.Keys(iter.Seq2[K, V](seq)))
}
// Values returns an iterator containing all the values in the ordered Map.
func (seq SeqMap[K, V]) Values() SeqSlice[V] {
return SeqSlice[V](iter.Values(iter.Seq2[K, V](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] {
iterSeqs := make([]iter.Seq2[K, V], len(seqs))
for i, s := range seqs {
iterSeqs[i] = iter.Seq2[K, V](s)
}
return SeqMap[K, V](iter.Chain2(iter.Seq2[K, V](seq), iterSeqs...))
}
// Count consumes the iterator, counting the number of iterations and returning it.
func (seq SeqMap[K, V]) Count() Int { return Int(iter.Count2(iter.Seq2[K, V](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[k] = v
return true
})
return collection
}
// 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 SeqMap[K, V](iter.Filter2(iter.Seq2[K, V](seq), fn))
}
// 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 SeqMap[K, V](iter.Exclude2(iter.Seq2[K, V](seq), fn))
}
// Find searches for an element in the iterator that satisfies the provided function.
//
// The function iterates through the elements of the iterator and returns the first element
// for which the provided function returns true.
//
// Params:
//
// - fn (func(K, V) bool): The function used to test elements for a condition.
//
// Returns:
//
// - Option[K, V]: An Option containing the first element that satisfies the condition; None if not found.
//
// Example usage:
//
// m := g.NewMap[int, int]()
// m.Set(1, 1)
// f := m.Iter().Find(func(_ int, v int) bool { return v == 1 })
// if f.IsSome() {
// print(f.Some().Key)
// }
//
// 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]] {
key, value, found := iter.Find2(iter.Seq2[K, V](seq), fn)
if found {
return Some(Pair[K, V]{Key: key, Value: value})
}
return None[Pair[K, V]]()
}
// 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)) { iter.ForEach2(iter.Seq2[K, V](seq), fn) }
// 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 SeqMap[K, V](iter.Inspect2(iter.Seq2[K, V](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 SeqMap[K, V](iter.Map2(iter.Seq2[K, V](seq), transform))
}
// FilterMap applies a function to each key-value pair and filters out None results.
//
// The function transforms and filters pairs in a single pass. Pairs where the function
// returns None are filtered out, and pairs where it returns Some are unwrapped
// and included in the result.
//
// Params:
//
// - fn (func(K, V) Option[Pair[K, V]]): The function that transforms and filters pairs.
// Returns Some(Pair{key, value}) to include the transformed pair, or None to filter it out.
//
// Returns:
//
// - SeqMap[K, V]: A sequence containing only the successfully transformed pairs.
//
// Example usage:
//
// configs := g.Map[string, string]{"host": "localhost", "port": "8080", "debug": "invalid"}
// validConfigs := configs.Iter().FilterMap(func(k string, v string) Option[Pair[string, string]] {
// if k == "port" || k == "host" {
// return Some(Pair[string, string]{Key: k, Value: v + "_validated"})
// }
// return None[Pair[string, string]]()
// })
// // validConfigs will yield: {"host": "localhost_validated", "port": "8080_validated"}
//
// users := g.Map[string, int]{"alice": 25, "bob": 17, "charlie": 30}
// adults := users.Iter().FilterMap(func(name string, age int) Option[Pair[string, int]] {
// if age >= 18 {
// return Some(Pair[string, int]{Key: name, Value: age})
// }
// return None[Pair[string, int]]()
// })
// // adults will yield: {"alice": 25, "charlie": 30}
func (seq SeqMap[K, V]) FilterMap(fn func(K, V) Option[Pair[K, V]]) SeqMap[K, V] {
return SeqMap[K, V](iter.FilterMap2(iter.Seq2[K, V](seq), func(k K, v V) (iter.Pair[K, V], bool) {
return fn(k, v).Option()
}))
}
// 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) { iter.Range2(iter.Seq2[K, V](seq), fn) }
// Context allows the iteration to be controlled with a context.Context.
func (seq SeqMap[K, V]) Context(ctx context.Context) SeqMap[K, V] {
return SeqMap[K, V](iter.Context2(iter.Seq2[K, V](seq), ctx))
}
// Next extracts the next key-value pair from the iterator and advances it.
//
// This method consumes the next key-value pair from the iterator and returns them wrapped in an Option.
// The iterator itself is modified to point to the remaining elements.
//
// Returns:
// - Option[Pair[K, V]]: Some(Pair{Key, Value}) if a pair exists, None if the iterator is exhausted.
func (seq *SeqMap[K, V]) Next() Option[Pair[K, V]] {
var pairs []Pair[K, V]
(*seq)(func(k K, v V) bool {
pairs = append(pairs, Pair[K, V]{Key: k, Value: v})
return true
})
if len(pairs) == 0 {
return None[Pair[K, V]]()
}
first := Some(pairs[0])
*seq = func(yield func(K, V) bool) {
for _, pair := range pairs[1:] {
if !yield(pair.Key, pair.Value) {
return
}
}
}
return first
}