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

471 lines
12 KiB
Go

package iter
import "slices"
// Next2 extracts the first key-value pair from the sequence and returns the remaining sequence.
// Returns (key, value, remainingSeq, true) if a pair exists, or (zeroK, zeroV, nil, false) if empty.
// This is similar to Rust's Iterator::next() method for key-value pairs.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "b", 3: "c"})
// k, v, rest, ok := iter.Next2(s)
// // k = 1, v = "a", ok = true (order not guaranteed for maps)
// // rest yields remaining pairs
//
// k2, v2, rest2, ok2 := iter.Next2(rest)
// // k2 = 2, v2 = "b", ok2 = true
// // rest2 yields remaining pairs
func Next2[K, V any](s Seq2[K, V]) (K, V, Seq2[K, V], bool) {
var firstK K
var firstV V
found := false
consumed := false
s(func(k K, v V) bool {
if !consumed {
firstK = k
firstV = v
found = true
consumed = true
return false
}
return true
})
if !found {
return firstK, firstV, nil, false
}
remaining := func(yield func(K, V) bool) {
skip := true
s(func(k K, v V) bool {
if skip {
skip = false
return true
}
return yield(k, v)
})
}
return firstK, firstV, remaining, true
}
// First2 returns the first key-value pair from the sequence.
// Returns (key, value, true) if a pair exists, or (zeroK, zeroV, false) if empty.
// This is similar to Rust's Iterator::first() method for key-value pairs.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "b", 3: "c"})
// k, v, ok := iter.First2(s) // might return: 1, "a", true
func First2[K, V any](s Seq2[K, V]) (K, V, bool) {
var resultK K
var resultV V
found := false
s(func(k K, v V) bool {
resultK = k
resultV = v
found = true
return false
})
return resultK, resultV, found
}
// Last2 returns the last key-value pair from the sequence.
// Returns (key, value, true) if a pair exists, or (zeroK, zeroV, false) if empty.
// This is similar to Rust's Iterator::last() method for key-value pairs.
//
// Example:
//
// pairs := []Pair[int, string]{{1, "a"}, {2, "b"}, {3, "c"}}
// s := iter.FromPairs(pairs)
// k, v, ok := iter.Last2(s) // 3, "c", true
func Last2[K, V any](s Seq2[K, V]) (K, V, bool) {
var resultK K
var resultV V
found := false
s(func(k K, v V) bool {
resultK = k
resultV = v
found = true
return true
})
return resultK, resultV, found
}
// ForEach2 applies a function to each key-value pair in the sequence.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "b"})
// iter.ForEach2(s, func(k int, v string) { fmt.Printf("%d: %s\n", k, v) })
func ForEach2[K, V any](s Seq2[K, V], fn func(K, V)) {
s(func(k K, v V) bool { fn(k, v); return true })
}
// Count2 returns the number of key-value pairs in the sequence.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "b"})
// count := iter.Count2(s) // 2
func Count2[K, V any](s Seq2[K, V]) int {
count := 0
s(func(K, V) bool { count++; return true })
return count
}
// Range2 applies a function to each key-value pair until it returns false.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "b", 3: "c"})
// iter.Range2(s, func(k int, v string) bool {
// fmt.Printf("%d: %s\n", k, v)
// return k != 2 // Stop at key 2
// })
func Range2[K, V any](s Seq2[K, V], fn func(K, V) bool) { s(fn) }
// Map2 applies a function to each key-value pair, producing a new Seq2.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "b"})
// iter.Map2(s, func(k int, v string) (int, string) {
// return k*10, strings.ToUpper(v)
// }) // yields: (10, "A"), (20, "B")
func Map2[K, V, K2, V2 any](s Seq2[K, V], f func(K, V) (K2, V2)) Seq2[K2, V2] {
return func(yield func(K2, V2) bool) {
s(func(k K, v V) bool {
k2, v2 := f(k, v)
return yield(k2, v2)
})
}
}
// Filter2 returns a new Seq2 containing only pairs that satisfy the predicate.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "bb", 3: "ccc"})
// iter.Filter2(s, func(k int, v string) bool { return len(v) > 1 })
// // yields pairs where value length > 1
func Filter2[K, V any](s Seq2[K, V], p func(K, V) bool) Seq2[K, V] {
return func(yield func(K, V) bool) {
s(func(k K, v V) bool {
if p(k, v) {
return yield(k, v)
}
return true
})
}
}
// Exclude2 returns a new Seq2 containing only pairs that do not satisfy the predicate.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "bb", 3: "ccc"})
// iter.Exclude2(s, func(k int, v string) bool { return len(v) > 1 })
// // yields pairs where value length <= 1
func Exclude2[K, V any](s Seq2[K, V], p func(K, V) bool) Seq2[K, V] {
return func(yield func(K, V) bool) {
s(func(k K, v V) bool {
if !p(k, v) {
return yield(k, v)
}
return true
})
}
}
// FilterMap2 applies a function to each key-value pair and filters out None results.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "bb", 3: "ccc"})
// iter.FilterMap2(s, func(k int, v string) (Pair[int, string], bool) {
// if len(v) > 1 {
// return Pair[int, string]{k*10, strings.ToUpper(v)}, true
// }
// return Pair[int, string]{}, false
// }) // yields: (20, "BB"), (30, "CCC")
func FilterMap2[K, V, K2, V2 any](s Seq2[K, V], f func(K, V) (Pair[K2, V2], bool)) Seq2[K2, V2] {
return func(yield func(K2, V2) bool) {
s(func(k K, v V) bool {
if pair, ok := f(k, v); ok {
return yield(pair.Key, pair.Value)
}
return true
})
}
}
// Find2 returns the first key-value pair that satisfies the predicate.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "bb", 3: "ccc"})
// k, v, ok := iter.Find2(s, func(k int, v string) bool { return len(v) > 1 })
// // might return: 2, "bb", true
func Find2[K, V any](s Seq2[K, V], p func(K, V) bool) (K, V, bool) {
var resultK K
var resultV V
found := false
s(func(k K, v V) bool {
if p(k, v) {
resultK = k
resultV = v
found = true
return false
}
return true
})
return resultK, resultV, found
}
// Keys extracts all keys from the Seq2 into a Seq.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "b"})
// iter.Keys(s) // yields: 1, 2 (order not guaranteed)
func Keys[K, V any](s Seq2[K, V]) Seq[K] {
return func(y func(K) bool) { s(func(k K, _ V) bool { return y(k) }) }
}
// Values extracts all values from the Seq2 into a Seq.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "b"})
// iter.Values(s) // yields: "a", "b" (order not guaranteed)
func Values[K, V any](s Seq2[K, V]) Seq[V] {
return func(y func(V) bool) { s(func(_ K, v V) bool { return y(v) }) }
}
// OrderByKey sorts the sequence by keys using the comparison function.
func OrderByKey[K, V any](s Seq2[K, V], less func(a, b K) bool) Seq2[K, V] {
buf := ToPairs(s)
slices.SortFunc(buf, func(a, b Pair[K, V]) int {
switch {
case less(a.Key, b.Key):
return -1
case less(b.Key, a.Key):
return 1
default:
return 0
}
})
return FromPairs(buf)
}
// OrderByValue sorts the sequence by values using the comparison function.
func OrderByValue[K, V any](s Seq2[K, V], less func(a, b V) bool) Seq2[K, V] {
buf := ToPairs(s)
slices.SortFunc(buf, func(a, b Pair[K, V]) int {
switch {
case less(a.Value, b.Value):
return -1
case less(b.Value, a.Value):
return 1
default:
return 0
}
})
return FromPairs(buf)
}
// Take2 returns the first n key-value pairs of the sequence.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "b", 3: "c"})
// iter.Take2(s, 2) // yields first 2 pairs
func Take2[K, V any](s Seq2[K, V], n int) Seq2[K, V] {
return func(yield func(K, V) bool) {
if n <= 0 {
return
}
count := 0
s(func(k K, v V) bool {
if count >= n {
return false
}
count++
return yield(k, v)
})
}
}
// Skip2 skips the first n key-value pairs and returns the rest.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "b", 3: "c"})
// iter.Skip2(s, 1) // yields all pairs except the first
func Skip2[K, V any](s Seq2[K, V], n int) Seq2[K, V] {
return func(yield func(K, V) bool) {
if n <= 0 {
s(yield)
return
}
count := 0
s(func(k K, v V) bool {
if count < n {
count++
return true
}
return yield(k, v)
})
}
}
// StepBy2 returns every nth key-value pair from the sequence.
//
// Example:
//
// pairs := []Pair[int, string]{{1, "a"}, {2, "b"}, {3, "c"}, {4, "d"}}
// s := iter.FromPairs(pairs)
// iter.StepBy2(s, 2) // yields: (1, "a"), (3, "c")
func StepBy2[K, V any](s Seq2[K, V], step int) Seq2[K, V] {
return func(yield func(K, V) bool) {
if step <= 0 {
return
}
index := 0
s(func(k K, v V) bool {
if index%step == 0 {
if !yield(k, v) {
return false
}
}
index++
return true
})
}
}
// SortBy2 sorts the sequence using the provided comparison function on Pair pairs.
func SortBy2[K, V any](s Seq2[K, V], less func(a, b Pair[K, V]) bool) Seq2[K, V] {
buf := ToPairs(s)
slices.SortFunc(buf, func(a, b Pair[K, V]) int {
if less(a, b) {
return -1
}
if less(b, a) {
return 1
}
return 0
})
return FromPairs(buf)
}
// Inspect2 applies a function to each key-value pair for side effects while passing through the original pairs.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "b"})
// iter.Inspect2(s, func(k int, v string) { fmt.Printf("Processing: %d=%s\n", k, v) })
func Inspect2[K, V any](s Seq2[K, V], fn func(K, V)) Seq2[K, V] {
return func(yield func(K, V) bool) { s(func(k K, v V) bool { fn(k, v); return yield(k, v) }) }
}
// Any2 returns true if any key-value pair satisfies the predicate.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "bb"})
// hasLongValue := iter.Any2(s, func(k int, v string) bool { return len(v) > 1 }) // true
func Any2[K, V any](s Seq2[K, V], p func(K, V) bool) bool {
found := false
s(func(k K, v V) bool {
if p(k, v) {
found = true
return false
}
return true
})
return found
}
// All2 returns true if all key-value pairs satisfy the predicate.
//
// Example:
//
// s := iter.FromMap(map[int]string{1: "a", 2: "b"})
// allShortValues := iter.All2(s, func(k int, v string) bool { return len(v) == 1 }) // true
func All2[K, V any](s Seq2[K, V], p func(K, V) bool) bool {
all := true
s(func(k K, v V) bool {
if !p(k, v) {
all = false
return false
}
return true
})
return all
}
// Fold2 reduces the Seq2 to a single value using an accumulator.
//
// Example:
//
// s := iter.FromMap(map[int]int{1: 10, 2: 20, 3: 30})
// sum := iter.Fold2(s, 0, func(acc, k, v int) int { return acc + k + v }) // 66
func Fold2[K, V, A any](s Seq2[K, V], acc A, f func(A, K, V) A) A {
s(func(k K, v V) bool { acc = f(acc, k, v); return true })
return acc
}
// Reduce2 reduces the Seq2 to a single Pair pair.
// Returns false if the sequence is empty.
//
// Example:
//
// s := iter.FromMap(map[int]int{1: 10, 2: 20})
// result, ok := iter.Reduce2(s, func(a, b Pair[int, int]) Pair[int, int] {
// return Pair[int, int]{a.Key + b.Key, a.Value + b.Value}
// }) // Pair{3, 30}, true
func Reduce2[K, V any](s Seq2[K, V], f func(Pair[K, V], Pair[K, V]) Pair[K, V]) (Pair[K, V], bool) {
var result Pair[K, V]
first := true
s(func(k K, v V) bool {
kv := Pair[K, V]{k, v}
if first {
result = kv
first = false
} else {
result = f(result, kv)
}
return true
})
return result, !first
}
// Nth2 returns the nth key-value pair (0-indexed) from the sequence.
//
// Example:
//
// pairs := []Pair[int, string]{{1, "a"}, {2, "b"}, {3, "c"}}
// s := iter.FromPairs(pairs)
// k, v, ok := iter.Nth2(s, 1) // 2, "b", true
func Nth2[K, V any](s Seq2[K, V], n int) (K, V, bool) {
var resultK K
var resultV V
found := false
index := 0
s(func(k K, v V) bool {
if index == n {
resultK = k
resultV = v
found = true
return false
}
index++
return true
})
return resultK, resultV, found
}