mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-07-25 13:10:50 +02:00
07c8adaf76
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
383 lines
12 KiB
Go
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
|
|
}
|