Skip to main content
Help improve this documentation

This documentation is still new and evolving. If you spot any mistakes, unclear explanations, or missing details, please open an issue.

Your feedback helps us improve!

Iterator - Intersection helpersโ€‹

This page lists all intersection helpers, available in the it lo sub-package.

  • Returns true if an element is present in a collection.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(10)
    _ = yield(20)
    _ = yield(30)
    }
    has := it.Contains(seq, 20)
    // has == true
    seq := func(yield func(string) bool) {
    _ = yield("apple")
    _ = yield("banana")
    _ = yield("cherry")
    }
    has := it.Contains(seq, "orange")
    // has == false
    Prototype:
    func Contains[T comparable](collection iter.Seq[T], element T) bool
  • Returns the intersection between given collections (elements present in all collections).

    Examples:

    seq1 := func(yield func(int) bool) {
    _ = yield(1)
    _ = yield(2)
    _ = yield(3)
    _ = yield(4)
    }
    seq2 := func(yield func(int) bool) {
    _ = yield(2)
    _ = yield(3)
    _ = yield(5)
    }
    seq3 := func(yield func(int) bool) {
    _ = yield(3)
    _ = yield(2)
    _ = yield(6)
    }
    intersection := it.Intersect(seq1, seq2, seq3)
    var result []int
    for v := range intersection {
    result = append(result, v)
    }
    // result contains 2, 3 (elements present in all sequences)
    Prototype:
    func Intersect[T comparable, I ~func(func(T) bool)](lists ...I) I
  • Returns all distinct elements from given collections (union of all collections).

    Examples:

    seq1 := func(yield func(int) bool) {
    _ = yield(1)
    _ = yield(2)
    _ = yield(3)
    }
    seq2 := func(yield func(int) bool) {
    _ = yield(2)
    _ = yield(3)
    _ = yield(4)
    }
    seq3 := func(yield func(int) bool) {
    _ = yield(3)
    _ = yield(5)
    }
    union := it.Union(seq1, seq2, seq3)
    var result []int
    for v := range union {
    result = append(result, v)
    }
    // result contains 1, 2, 3, 4, 5 (all distinct elements)
    Prototype:
    func Union[T comparable, I ~func(func(T) bool)](lists ...I) I
  • Returns true if all elements of a subset are contained in a collection.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(1)
    _ = yield(2)
    _ = yield(3)
    _ = yield(4)
    _ = yield(5)
    }
    hasAll := it.Every(seq, 2, 4)
    // hasAll == true
    seq := func(yield func(string) bool) {
    _ = yield("apple")
    _ = yield("banana")
    _ = yield("cherry")
    }
    hasAll := it.Every(seq, "apple", "orange")
    // hasAll == false (orange is not in collection)
    Prototype:
    func Every[T comparable](collection iter.Seq[T], subset ...T) bool
  • Returns true if at least one element of a subset is contained in a collection.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(1)
    _ = yield(2)
    _ = yield(3)
    _ = yield(4)
    _ = yield(5)
    }
    hasAny := it.Some(seq, 2, 6)
    // hasAny == true (2 is in collection)
    seq := func(yield func(string) bool) {
    _ = yield("apple")
    _ = yield("banana")
    _ = yield("cherry")
    }
    hasAny := it.Some(seq, "orange", "grape")
    // hasAny == false (neither is in collection)
    Prototype:
    func Some[T comparable](collection iter.Seq[T], subset ...T) bool
  • Returns a sequence excluding all given values.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(1)
    _ = yield(2)
    _ = yield(3)
    _ = yield(4)
    _ = yield(5)
    }
    filtered := it.Without(seq, 2, 4)
    var result []int
    for v := range filtered {
    result = append(result, v)
    }
    // result contains 1, 3, 5
    Prototype:
    func Without[T comparable, I ~func(func(T) bool)](collection I, exclude ...T) I
  • Returns true if predicate function returns true for any element in the collection.

    Will iterate through the entire sequence if predicate never returns true.

    Examples:

    // Check if collection contains an even number
    numbers := it.Slice([]int{1, 3, 5, 7, 9})
    hasEven := it.ContainsBy(numbers, func(n int) bool { return n%2 == 0 })
    // hasEven: false

    numbers = it.Slice([]int{1, 3, 5, 8, 9})
    hasEven = it.ContainsBy(numbers, func(n int) bool { return n%2 == 0 })
    // hasEven: true

    // Check if collection contains a string with specific prefix
    words := it.Slice([]string{"hello", "world", "go", "lang"})
    hasPrefix := it.ContainsBy(words, func(s string) bool { return strings.HasPrefix(s, "go") })
    // hasPrefix: true

    // Check if collection contains a person with specific age
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 35},
    })
    hasAge30 := it.ContainsBy(people, func(p Person) bool { return p.Age == 30 })
    // hasAge30: true

    hasAge40 := it.ContainsBy(people, func(p Person) bool { return p.Age == 40 })
    // hasAge40: false

    // Check if collection contains an element with specific property
    strings := it.Slice([]string{"apple", "banana", "cherry"})
    hasLongString := it.ContainsBy(strings, func(s string) bool { return len(s) > 5 })
    // hasLongString: true

    // Check if collection contains negative numbers
    numbers = it.Slice([]int{1, -2, 3, 4, -5})
    hasNegative := it.ContainsBy(numbers, func(n int) bool { return n < 0 })
    // hasNegative: true

    // Check if collection contains valid email
    emails := it.Slice([]string{"[email protected]", "invalid-email", "[email protected]"})
    hasValidEmail := it.ContainsBy(emails, func(email string) bool {
    return strings.Contains(email, "@") && strings.Contains(email, ".")
    })
    // hasValidEmail: true

    // Check empty collection
    empty := it.Slice([]int{})
    hasAny := it.ContainsBy(empty, func(n int) bool { return n > 0 })
    // hasAny: false

    // Check for nil pointers (with pointer slice)
    ptrs := it.Slice([]*int{ptr(5), nil, ptr(10)})
    hasNil := it.ContainsBy(ptrs, func(p *int) bool { return p == nil })
    // hasNil: true
    Prototype:
    func ContainsBy[T any](collection iter.Seq[T], predicate func(item T) bool) bool
  • Returns true if the predicate returns true for all elements in the collection or if the collection is empty.

    Will iterate through the entire sequence if predicate never returns false.

    Examples:

    // Check if all numbers are positive
    numbers := it.Slice([]int{1, 3, 5, 7, 9})
    allPositive := it.EveryBy(numbers, func(n int) bool { return n > 0 })
    // allPositive: true

    numbers = it.Slice([]int{1, -3, 5, 7, 9})
    allPositive = it.EveryBy(numbers, func(n int) bool { return n > 0 })
    // allPositive: false

    // Check if all strings have minimum length
    words := it.Slice([]string{"hello", "world", "go", "lang"})
    allLongEnough := it.EveryBy(words, func(s string) bool { return len(s) >= 2 })
    // allLongEnough: true

    allVeryLong := it.EveryBy(words, func(s string) bool { return len(s) >= 5 })
    // allVeryLong: false

    // Check if all people are adults
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 35},
    })
    allAdults := it.EveryBy(people, func(p Person) bool { return p.Age >= 18 })
    // allAdults: true

    minors := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 15}, // Not adult
    {Name: "Charlie", Age: 35},
    })
    allAdults = it.EveryBy(minors, func(p Person) bool { return p.Age >= 18 })
    // allAdults: false

    // Check if all numbers are even
    numbers = it.Slice([]int{2, 4, 6, 8, 10})
    allEven := it.EveryBy(numbers, func(n int) bool { return n%2 == 0 })
    // allEven: true

    numbers = it.Slice([]int{2, 4, 6, 7, 10}) // 7 is odd
    allEven = it.EveryBy(numbers, func(n int) bool { return n%2 == 0 })
    // allEven: false

    // Check if all strings are lowercase
    strings := it.Slice([]string{"hello", "world", "go", "lang"})
    allLowercase := it.EveryBy(strings, func(s string) bool { return s == strings.ToLower(s) })
    // allLowercase: true

    strings = it.Slice([]string{"hello", "World", "go", "lang"}) // "World" has uppercase
    allLowercase = it.EveryBy(strings, func(s string) bool { return s == strings.ToLower(s) })
    // allLowercase: false

    // Empty collection returns true
    empty := it.Slice([]int{})
    allPositive := it.EveryBy(empty, func(n int) bool { return n > 0 })
    // allPositive: true

    // Check if all emails are valid
    emails := it.Slice([]string{"[email protected]", "[email protected]", "[email protected]"})
    allValid := it.EveryBy(emails, func(email string) bool {
    return strings.Contains(email, "@") && strings.Contains(email, ".")
    })
    // allValid: true

    emails = it.Slice([]string{"[email protected]", "invalid-email", "[email protected]"})
    allValid = it.EveryBy(emails, func(email string) bool {
    return strings.Contains(email, "@") && strings.Contains(email, ".")
    })
    // allValid: false
    Prototype:
    func EveryBy[T any](collection iter.Seq[T], predicate func(item T) bool) bool
  • Returns true if the predicate returns true for any of the elements in the collection.

    If the collection is empty SomeBy returns false.
    Will iterate through the entire sequence if predicate never returns true.

    Examples:

    // Check if any number is even
    numbers := it.Slice([]int{1, 3, 5, 7, 9})
    hasEven := it.SomeBy(numbers, func(n int) bool { return n%2 == 0 })
    // hasEven: false

    numbers = it.Slice([]int{1, 3, 5, 8, 9})
    hasEven = it.SomeBy(numbers, func(n int) bool { return n%2 == 0 })
    // hasEven: true

    // Check if any string starts with specific prefix
    words := it.Slice([]string{"hello", "world", "go", "lang"})
    hasGoPrefix := it.SomeBy(words, func(s string) bool { return strings.HasPrefix(s, "go") })
    // hasGoPrefix: true

    hasPythonPrefix := it.SomeBy(words, func(s string) bool { return strings.HasPrefix(s, "python") })
    // hasPythonPrefix: false

    // Check if any person is a teenager
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 35},
    })
    hasTeenager := it.SomeBy(people, func(p Person) bool { return p.Age >= 13 && p.Age <= 19 })
    // hasTeenager: false

    teenagers := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 16}, // Teenager
    {Name: "Charlie", Age: 35},
    })
    hasTeenager = it.SomeBy(teenagers, func(p Person) bool { return p.Age >= 13 && p.Age <= 19 })
    // hasTeenager: true

    // Check if any number is greater than 100
    numbers = it.Slice([]int{1, 3, 5, 7, 9})
    hasLargeNumber := it.SomeBy(numbers, func(n int) bool { return n > 100 })
    // hasLargeNumber: false

    numbers = it.Slice([]int{1, 3, 5, 150, 9})
    hasLargeNumber = it.SomeBy(numbers, func(n int) bool { return n > 100 })
    // hasLargeNumber: true

    // Check if any string contains a substring
    strings := it.Slice([]string{"hello", "world", "go", "lang"})
    hasWorld := it.SomeBy(strings, func(s string) bool { return strings.Contains(s, "world") })
    // hasWorld: true

    hasPython := it.SomeBy(strings, func(s string) bool { return strings.Contains(s, "python") })
    // hasPython: false

    // Empty collection returns false
    empty := it.Slice([]int{})
    hasAny := it.SomeBy(empty, func(n int) bool { return n > 0 })
    // hasAny: false

    // Check if any email is from specific domain
    emails := it.Slice([]string{"[email protected]", "[email protected]", "[email protected]"})
    hasGmail := it.SomeBy(emails, func(email string) bool { return strings.HasSuffix(email, "@gmail.com") })
    // hasGmail: true

    hasYahoo := it.SomeBy(emails, func(email string) bool { return strings.HasSuffix(email, "@yahoo.com") })
    // hasYahoo: false

    // Check if any string is palindrome
    words := it.Slice([]string{"level", "hello", "world", "radar"})
    hasPalindrome := it.SomeBy(words, func(s string) bool {
    return s == reverseString(s)
    })
    // hasPalindrome: true ("level" and "radar" are palindromes)
    Prototype:
    func SomeBy[T any](collection iter.Seq[T], predicate func(item T) bool) bool
  • Returns true if no element of a subset is contained in a collection or if the subset is empty.

    Will iterate through the entire sequence if subset elements never match.

    Examples:

    // Check if collection contains none of the forbidden values
    numbers := it.Slice([]int{1, 3, 5, 7, 9})
    forbidden := []int{2, 4, 6, 8}
    hasNone := it.None(numbers, forbidden...)
    // hasNone: true

    numbers = it.Slice([]int{1, 3, 5, 8, 9})
    hasNone = it.None(numbers, forbidden...)
    // hasNone: false (8 is in both collection and forbidden)

    // Check if collection contains none of unwanted words
    words := it.Slice([]string{"hello", "world", "go", "lang"})
    unwanted := []string{"bad", "evil", "wrong"}
    hasNone := it.None(words, unwanted...)
    // hasNone: true

    words = it.Slice([]string{"hello", "bad", "go", "lang"})
    hasNone = it.None(words, unwanted...)
    // hasNone: false ("bad" is in both)

    // Check if collection contains none of specific IDs
    ids := it.Slice([]int{101, 102, 103, 104})
    restrictedIds := []int{201, 202, 203}
    hasNone := it.None(ids, restrictedIds...)
    // hasNone: true

    ids = it.Slice([]int{101, 102, 203, 104})
    hasNone = it.None(ids, restrictedIds...)
    // hasNone: false (203 is restricted)

    // Check with empty subset (always returns true)
    numbers = it.Slice([]int{1, 3, 5, 7, 9})
    hasNone = it.None(numbers)
    // hasNone: true

    // Check with strings containing specific characters
    words := it.Slice([]string{"hello", "world", "go", "lang"})
    forbiddenChars := []string{"@", "#", "$"}
    hasNone := it.None(words, forbiddenChars...)
    // hasNone: true

    words = it.Slice([]string{"hello", "world", "go@"})
    hasNone = it.None(words, forbiddenChars...)
    // hasNone: false (contains "@")

    // Check if collection has none of problematic status codes
    statusCodes := it.Slice([]int{200, 201, 204})
    errorCodes := []int{400, 401, 403, 404, 500}
    hasNone := it.None(statusCodes, errorCodes...)
    // hasNone: true

    statusCodes = it.Slice([]int{200, 404, 204})
    hasNone = it.None(statusCodes, errorCodes...)
    // hasNone: false (contains 404)

    // Check with empty collection (always returns true)
    empty := it.Slice([]int{})
    hasNone = it.None(empty, 1, 2, 3)
    // hasNone: true

    // Check for none of forbidden usernames
    usernames := it.Slice([]string{"alice", "bob", "charlie"})
    forbiddenUsers := []string{"admin", "root", "system"}
    hasNone := it.None(usernames, forbiddenUsers...)
    // hasNone: true

    usernames = it.Slice([]string{"alice", "admin", "charlie"})
    hasNone = it.None(usernames, forbiddenUsers...)
    // hasNone: false ("admin" is forbidden)
    Prototype:
    func None[T comparable](collection iter.Seq[T], subset ...T) bool
  • Returns true if the predicate returns true for none of the elements in the collection or if the collection is empty.

    Will iterate through the entire sequence if predicate never returns true.

    Examples:

    // Check if collection has no even numbers
    numbers := it.Slice([]int{1, 3, 5, 7, 9})
    hasNoEvens := it.NoneBy(numbers, func(n int) bool { return n%2 == 0 })
    // hasNoEvens: true

    numbers = it.Slice([]int{1, 3, 5, 8, 9})
    hasNoEvens = it.NoneBy(numbers, func(n int) bool { return n%2 == 0 })
    // hasNoEvens: false (8 is even)

    // Check if collection has no strings with specific prefix
    words := it.Slice([]string{"hello", "world", "go", "lang"})
    hasNoGoPrefix := it.NoneBy(words, func(s string) bool { return strings.HasPrefix(s, "go") })
    // hasNoGoPrefix: false ("go" has go prefix)

    hasNoPythonPrefix := it.NoneBy(words, func(s string) bool { return strings.HasPrefix(s, "python") })
    // hasNoPythonPrefix: true

    // Check if collection has no minors
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 35},
    })
    hasNoMinors := it.NoneBy(people, func(p Person) bool { return p.Age < 18 })
    // hasNoMinors: true

    withMinor := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 16}, // Minor
    {Name: "Charlie", Age: 35},
    })
    hasNoMinors = it.NoneBy(withMinor, func(p Person) bool { return p.Age < 18 })
    // hasNoMinors: false

    // Check if collection has no negative numbers
    numbers = it.Slice([]int{1, 3, 5, 7, 9})
    hasNoNegatives := it.NoneBy(numbers, func(n int) bool { return n < 0 })
    // hasNoNegatives: true

    numbers = it.Slice([]int{1, -3, 5, 7, 9})
    hasNoNegatives = it.NoneBy(numbers, func(n int) bool { return n < 0 })
    // hasNoNegatives: false (-3 is negative)

    // Check if collection has no uppercase strings
    strings := it.Slice([]string{"hello", "world", "go", "lang"})
    hasNoUppercase := it.NoneBy(strings, func(s string) bool { return s != strings.ToLower(s) })
    // hasNoUppercase: true

    strings = it.Slice([]string{"hello", "World", "go", "lang"}) // "World" has uppercase
    hasNoUppercase = it.NoneBy(strings, func(s string) bool { return s != strings.ToLower(s) })
    // hasNoUppercase: false

    // Empty collection returns true
    empty := it.Slice([]int{})
    hasNoEvens := it.NoneBy(empty, func(n int) bool { return n%2 == 0 })
    // hasNoEvens: true

    // Check if collection has no invalid emails
    emails := it.Slice([]string{"[email protected]", "[email protected]", "[email protected]"})
    hasNoInvalid := it.NoneBy(emails, func(email string) bool {
    return !strings.Contains(email, "@") || !strings.Contains(email, ".")
    })
    // hasNoInvalid: true

    emails = it.Slice([]string{"[email protected]", "invalid-email", "[email protected]"})
    hasNoInvalid = it.NoneBy(emails, func(email string) bool {
    return !strings.Contains(email, "@") || !strings.Contains(email, ".")
    })
    // hasNoInvalid: false

    // Check if collection has no numbers greater than 100
    numbers = it.Slice([]int{1, 3, 5, 7, 9})
    hasNoLargeNumbers := it.NoneBy(numbers, func(n int) bool { return n > 100 })
    // hasNoLargeNumbers: true

    numbers = it.Slice([]int{1, 3, 5, 150, 9})
    hasNoLargeNumbers = it.NoneBy(numbers, func(n int) bool { return n > 100 })
    // hasNoLargeNumbers: false (150 > 100)

    // Check if collection has no strings shorter than 3 characters
    words := it.Slice([]string{"hello", "world", "go", "lang"})
    hasNoShortWords := it.NoneBy(words, func(s string) bool { return len(s) < 3 })
    // hasNoShortWords: false ("go" has length 2)
    Prototype:
    func NoneBy[T any](collection iter.Seq[T], predicate func(item T) bool) bool
  • Filters a sequence by excluding elements whose extracted keys match any in the exclude list.

    Returns a sequence containing only the elements whose keys are not in the exclude list.
    Will allocate a map large enough to hold all distinct excludes.

    Examples:

    // Exclude people by specific ages
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 35},
    {Name: "Diana", Age: 30}, // Same age as Alice
    })

    filtered := it.WithoutBy(people, func(p Person) int { return p.Age }, 30)
    // filtered: sequence with Bob (age 25) and Charlie (age 35)

    // Exclude strings by their length
    words := it.Slice([]string{"hello", "world", "hi", "go", "bye"})
    filtered := it.WithoutBy(words, func(s string) int { return len(s) }, 2)
    // filtered: sequence with "hello" (5), "world" (5), "bye" (3)
    // excludes "hi" and "go" (both length 2)

    // Exclude items by first letter
    items := it.Slice([]string{"apple", "apricot", "banana", "blueberry", "cherry"})
    filtered := it.WithoutBy(items, func(s string) byte { return s[0] }, 'b')
    // filtered: sequence with "apple", "apricot", "cherry"
    // excludes "banana" and "blueberry" (both start with 'b')

    // Exclude numbers by modulo
    numbers := it.Slice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
    filtered := it.WithoutBy(numbers, func(n int) int { return n % 3 }, 1)
    // filtered: sequence with numbers where n % 3 != 1
    // excludes 1, 4, 7, 10 (all have remainder 1)

    // Exclude emails by domain
    type Email struct {
    Address string
    }
    emails := it.Slice([]Email{
    {Address: "[email protected]"},
    {Address: "[email protected]"},
    {Address: "[email protected]"},
    {Address: "[email protected]"},
    })
    filtered := it.WithoutBy(emails, func(e Email) string {
    parts := strings.Split(e.Address, "@")
    if len(parts) > 1 {
    return parts[1]
    }
    return ""
    }, "example.com")
    // filtered: sequence with gmail.com and yahoo.com emails

    // Exclude orders by customer ID
    type Order struct {
    ID string
    CustomerID string
    ProductID string
    }
    orders := it.Slice([]Order{
    {ID: "1", CustomerID: "A", ProductID: "X"},
    {ID: "2", CustomerID: "B", ProductID: "Y"},
    {ID: "3", CustomerID: "A", ProductID: "Z"},
    {ID: "4", CustomerID: "C", ProductID: "W"},
    })
    filtered := it.WithoutBy(orders, func(o Order) string { return o.CustomerID }, "A")
    // filtered: sequence with orders from customers B and C

    // Exclude strings by case-insensitive value
    words := it.Slice([]string{"Hello", "hello", "WORLD", "world", "Go"})
    filtered := it.WithoutBy(words, func(s string) string { return strings.ToLower(s) }, "hello")
    // filtered: sequence with "WORLD", "world", "Go"
    // excludes both "Hello" and "hello" (both become "hello" when lowercased)

    // Exclude dates by month
    import "time"
    dates := it.Slice([]time.Time{
    time.Date(2023, 1, 15, 0, 0, 0, 0, time.UTC),
    time.Date(2023, 2, 20, 0, 0, 0, 0, time.UTC),
    time.Date(2023, 1, 25, 0, 0, 0, 0, time.UTC),
    time.Date(2023, 3, 10, 0, 0, 0, 0, time.UTC),
    })
    filtered := it.WithoutBy(dates, func(t time.Time) time.Month { return t.Month() }, time.January)
    // filtered: sequence with February and March dates

    // Exclude multiple values
    numbers := it.Slice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
    filtered := it.WithoutBy(numbers, func(n int) int { return n % 2 }, 0, 1)
    // filtered: empty sequence (all numbers are either even (0) or odd (1))

    // Exclude by custom function result
    type Product struct {
    Name string
    Price float64
    }
    products := it.Slice([]Product{
    {Name: "Book", Price: 19.99},
    {Name: "Pen", Price: 1.99},
    {Name: "Laptop", Price: 999.99},
    {Name: "Pencil", Price: 0.99},
    })
    // Exclude products with price < $10
    filtered := it.WithoutBy(products, func(p Product) string {
    if p.Price < 10 {
    return "cheap"
    }
    return "expensive"
    }, "cheap")
    // filtered: sequence with "Book" and "Laptop"
    Prototype:
    func WithoutBy[T any, K comparable, I ~func(func(T) bool)](collection I, transform func(item T) K, exclude ...K) I
  • Returns a sequence excluding the elements at the specified indices.

    Will allocate a map large enough to hold all distinct indices.

    Examples:

    // Exclude elements at specific indices
    numbers := it.Slice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
    filtered := it.WithoutNth(numbers, 2, 5, 8)
    // filtered: sequence with 1, 2, 4, 5, 7, 8, 10
    // excludes elements at indices 2 (3), 5 (6), and 8 (9)

    // Exclude single element
    words := it.Slice([]string{"hello", "world", "go", "lang", "awesome"})
    filtered := it.WithoutNth(words, 1)
    // filtered: sequence with "hello", "go", "lang", "awesome"
    // excludes "world" at index 1

    // Exclude first element
    numbers = it.Slice([]int{10, 20, 30, 40, 50})
    filtered = it.WithoutNth(numbers, 0)
    // filtered: sequence with 20, 30, 40, 50
    // excludes 10 at index 0

    // Exclude last element
    numbers = it.Slice([]int{10, 20, 30, 40, 50})
    filtered = it.WithoutNth(numbers, 4)
    // filtered: sequence with 10, 20, 30, 40
    // excludes 50 at index 4

    // Exclude multiple elements including duplicates
    words = it.Slice([]string{"a", "b", "c", "d", "e", "f", "g"})
    filtered = it.WithoutNth(words, 1, 3, 1, 5)
    // filtered: sequence with "a", "c", "e", "g"
    // excludes elements at indices 1 (b), 3 (d), and 5 (f)
    // index 1 appears twice but element at index 1 is only excluded once

    // Exclude with negative indices (out of bounds, no effect)
    numbers = it.Slice([]int{1, 2, 3, 4, 5})
    filtered = it.WithoutNth(numbers, -1, 2)
    // filtered: sequence with 1, 2, 4, 5
    // excludes element at index 2 (3), ignores -1

    // Exclude with indices larger than collection (out of bounds, no effect)
    numbers = it.Slice([]int{1, 2, 3, 4, 5})
    filtered = it.WithoutNth(numbers, 10, 2)
    // filtered: sequence with 1, 2, 4, 5
    // excludes element at index 2 (3), ignores 10

    // Exclude all elements
    numbers = it.Slice([]int{1, 2, 3, 4, 5})
    filtered = it.WithoutNth(numbers, 0, 1, 2, 3, 4)
    // filtered: empty sequence

    // Exclude no indices (returns original)
    numbers = it.Slice([]int{1, 2, 3, 4, 5})
    filtered = it.WithoutNth(numbers)
    // filtered: sequence with 1, 2, 3, 4, 5 (unchanged)

    // With structs
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 35},
    {Name: "Diana", Age: 28},
    {Name: "Eve", Age: 32},
    })
    filtered := it.WithoutNth(people, 1, 3)
    // filtered: sequence with Alice, Charlie, Eve
    // excludes Bob at index 1 and Diana at index 3

    // With mixed valid and invalid indices
    words = it.Slice([]string{"first", "second", "third", "fourth"})
    filtered = it.WithoutNth(words, -1, 1, 10, 2)
    // filtered: sequence with "first", "fourth"
    // excludes "second" at index 1 and "third" at index 2
    // ignores -1 and 10 as they are out of bounds

    // Exclude from empty collection
    empty := it.Slice([]int{})
    filtered := it.WithoutNth(empty, 0, 1, 2)
    // filtered: empty sequence
    Prototype:
    func WithoutNth[T comparable, I ~func(func(T) bool)](collection I, nths ...int) I
  • Returns true if lists contain the same set of elements (including empty set).

    If there are duplicate elements, the number of occurrences in each list should match.
    The order of elements is not checked.
    Will iterate through each sequence before returning and allocate a map large enough to hold all distinct elements.
    Long heterogeneous input sequences can cause excessive memory usage.

    Examples:

    // Lists with same elements in different order
    list1 := it.Slice([]int{1, 2, 3, 4, 5})
    list2 := it.Slice([]int{5, 4, 3, 2, 1})
    match := it.ElementsMatch(list1, list2)
    // match: true

    // Lists with different elements
    list1 = it.Slice([]int{1, 2, 3, 4, 5})
    list2 = it.Slice([]int{1, 2, 3, 4, 6})
    match = it.ElementsMatch(list1, list2)
    // match: false (5 vs 6)

    // Lists with duplicates
    list1 = it.Slice([]int{1, 2, 2, 3, 4})
    list2 = it.Slice([]int{4, 3, 2, 1, 2})
    match = it.ElementsMatch(list1, list2)
    // match: true (both have two 2's)

    // Lists with different number of duplicates
    list1 = it.Slice([]int{1, 2, 2, 3, 4})
    list2 = it.Slice([]int{4, 3, 2, 1, 1})
    match = it.ElementsMatch(list1, list2)
    // match: false (list1 has two 2's, list2 has two 1's)

    // Empty lists
    empty1 := it.Slice([]int{})
    empty2 := it.Slice([]int{})
    match = it.ElementsMatch(empty1, empty2)
    // match: true

    // One empty, one not empty
    empty := it.Slice([]int{})
    nonEmpty := it.Slice([]int{1, 2, 3})
    match = it.ElementsMatch(empty, nonEmpty)
    // match: false

    // String lists
    words1 := it.Slice([]string{"hello", "world", "go"})
    words2 := it.Slice([]string{"go", "hello", "world"})
    match := it.ElementsMatch(words1, words2)
    // match: true

    words1 = it.Slice([]string{"hello", "world", "go"})
    words2 = it.Slice([]string{"go", "hello", "golang"})
    match = it.ElementsMatch(words1, words2)
    // match: false

    // Struct lists
    type Person struct {
    Name string
    Age int
    }
    people1 := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 35},
    })
    people2 := it.Slice([]Person{
    {Name: "Charlie", Age: 35},
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    })
    match := it.ElementsMatch(people1, people2)
    // match: true

    // Different lengths
    list1 = it.Slice([]int{1, 2, 3})
    list2 = it.Slice([]int{1, 2, 3, 4})
    match = it.ElementsMatch(list1, list2)
    // match: false

    // Same elements but different counts
    list1 = it.Slice([]int{1, 1, 2, 3})
    list2 = it.Slice([]int{1, 2, 2, 3})
    match = it.ElementsMatch(list1, list2)
    // match: false (list1 has two 1's, list2 has two 2's)

    // Boolean values
    bools1 := it.Slice([]bool{true, false, true})
    bools2 := it.Slice([]bool{true, true, false})
    match := it.ElementsMatch(bools1, bools2)
    // match: true

    // Different boolean counts
    bools1 = it.Slice([]bool{true, false, true})
    bools2 = it.Slice([]bool{true, false, false})
    match = it.ElementsMatch(bools1, bools2)
    // match: false

    // Lists with same single element
    list1 = it.Slice([]int{42})
    list2 = it.Slice([]int{42})
    match = it.ElementsMatch(list1, list2)
    // match: true

    // Lists with different single elements
    list1 = it.Slice([]int{42})
    list2 = it.Slice([]int{43})
    match = it.ElementsMatch(list1, list2)
    // match: false
    Prototype:
    func ElementsMatch[T comparable](list1, list2 iter.Seq[T]) bool
  • Returns true if lists contain the same set of elements' keys (including empty set).

    If there are duplicate keys, the number of occurrences in each list should match.
    The order of elements is not checked.
    Will iterate through each sequence before returning and allocate a map large enough to hold all distinct transformed elements.
    Long heterogeneous input sequences can cause excessive memory usage.

    Examples:

    // Match people by age (ignoring names)
    type Person struct {
    Name string
    Age int
    }
    people1 := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 35},
    })
    people2 := it.Slice([]Person{
    {Name: "David", Age: 35},
    {Name: "Eve", Age: 25},
    {Name: "Frank", Age: 30},
    })
    match := it.ElementsMatchBy(people1, people2, func(p Person) int { return p.Age })
    // match: true (both have ages 25, 30, 35)

    // Match by string length
    words1 := it.Slice([]string{"hello", "world", "go", "lang"})
    words2 := it.Slice([]string{"short", "longer", "golang", "python"})
    match = it.ElementsMatchBy(words1, words2, func(s string) int { return len(s) })
    // match: false (lengths: 5,5,2,4 vs 6,6,6,6)

    // Match by first character
    items1 := it.Slice([]string{"apple", "apricot", "banana", "blueberry"})
    items2 := it.Slice([]string{"ant", "anchor", "boat", "berry"})
    match = it.ElementsMatchBy(items1, items2, func(s string) byte { return s[0] })
    // match: true (both start with a, a, b, b)

    // Match emails by domain
    type Email struct {
    Address string
    }
    emails1 := it.Slice([]Email{
    {Address: "[email protected]"},
    {Address: "[email protected]"},
    {Address: "[email protected]"},
    })
    emails2 := it.Slice([]Email{
    {Address: "[email protected]"},
    {Address: "[email protected]"},
    {Address: "[email protected]"},
    })
    match = it.ElementsMatchBy(emails1, emails2, func(e Email) string {
    parts := strings.Split(e.Address, "@")
    if len(parts) > 1 {
    return parts[1]
    }
    return ""
    })
    // match: true (both have domains: example.com, gmail.com, example.com)

    // Match by modulo operation
    numbers1 := it.Slice([]int{1, 2, 3, 4, 5, 6})
    numbers2 := it.Slice([]int{7, 8, 9, 10, 11, 12})
    match = it.ElementsMatchBy(numbers1, numbers2, func(n int) int { return n % 3 })
    // match: true (remainders: 1,2,0,1,2,0 vs 1,2,0,1,2,0)

    // Match by case-insensitive strings
    strings1 := it.Slice([]string{"Hello", "World", "GO"})
    strings2 := it.Slice([]string{"hello", "world", "go"})
    match = it.ElementsMatchBy(strings1, strings2, func(s string) string { return strings.ToLower(s) })
    // match: true

    // Match orders by customer ID (ignoring order details)
    type Order struct {
    ID string
    CustomerID string
    ProductID string
    }
    orders1 := it.Slice([]Order{
    {ID: "1", CustomerID: "A", ProductID: "X"},
    {ID: "2", CustomerID: "B", ProductID: "Y"},
    {ID: "3", CustomerID: "A", ProductID: "Z"},
    })
    orders2 := it.Slice([]Order{
    {ID: "4", CustomerID: "B", ProductID: "W"},
    {ID: "5", CustomerID: "A", ProductID: "V"},
    {ID: "6", CustomerID: "A", ProductID: "U"},
    })
    match = it.ElementsMatchBy(orders1, orders2, func(o Order) string { return o.CustomerID })
    // match: true (both have customer IDs: A, B, A)

    // Match dates by year-month (ignoring day)
    import "time"
    dates1 := it.Slice([]time.Time{
    time.Date(2023, 1, 15, 0, 0, 0, 0, time.UTC),
    time.Date(2023, 2, 20, 0, 0, 0, 0, time.UTC),
    time.Date(2023, 1, 25, 0, 0, 0, 0, time.UTC),
    })
    dates2 := it.Slice([]time.Time{
    time.Date(2023, 1, 5, 0, 0, 0, 0, time.UTC),
    time.Date(2023, 2, 10, 0, 0, 0, 0, time.UTC),
    time.Date(2023, 1, 30, 0, 0, 0, 0, time.UTC),
    })
    match = it.ElementsMatchBy(dates1, dates2, func(t time.Time) string {
    return fmt.Sprintf("%d-%02d", t.Year(), t.Month())
    })
    // match: true (both have: 2023-01, 2023-02, 2023-01)

    // Match by category function
    type Product struct {
    Name string
    Price float64
    }
    products1 := it.Slice([]Product{
    {Name: "Book", Price: 19.99},
    {Name: "Pen", Price: 1.99},
    {Name: "Laptop", Price: 999.99},
    })
    products2 := it.Slice([]Product{
    {Name: "Pencil", Price: 0.99},
    {Name: "Phone", Price: 699.99},
    {Name: "Desk", Price: 199.99},
    })
    match = it.ElementsMatchBy(products1, products2, func(p Product) string {
    if p.Price < 10 {
    return "cheap"
    } else if p.Price < 100 {
    return "medium"
    }
    return "expensive"
    })
    // match: true (both have: medium, cheap, expensive)

    // Match by custom classification
    type Student struct {
    Name string
    Age int
    }
    students1 := it.Slice([]Student{
    {Name: "Alice", Age: 8},
    {Name: "Bob", Age: 15},
    {Name: "Charlie", Age: 20},
    })
    students2 := it.Slice([]Student{
    {Name: "Diana", Age: 25},
    {Name: "Eve", Age: 10},
    {Name: "Frank", Age: 12},
    })
    match = it.ElementsMatchBy(students1, students2, func(s Student) string {
    if s.Age < 12 {
    return "child"
    } else if s.Age < 18 {
    return "teen"
    }
    return "adult"
    })
    // match: false (students1: child, teen, adult vs students2: adult, child, child)
    Prototype:
    func ElementsMatchBy[T any, K comparable](list1, list2 iter.Seq[T], transform func(item T) K) bool