Skip to main content

Find - Iterator helpers

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

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!

  • Returns the index at which the first occurrence of a value is found in the sequence, or -1 if the value is not found. Scans the sequence from the beginning and returns the position of the first matching element.

    // Find existing element - returns first occurrence
    seq := func(yield func(int) bool) {
    _ = yield(10)
    _ = yield(20)
    _ = yield(30)
    _ = yield(20)
    }
    idx := it.IndexOf(seq, 20)
    // idx: 1 (first occurrence of 20)
    // Element not found - returns -1
    seq := func(yield func(string) bool) {
    _ = yield("apple")
    _ = yield("banana")
    _ = yield("cherry")
    }
    idx := it.IndexOf(seq, "orange")
    // idx: -1 (orange not found in sequence)
    // Empty sequence - returns -1
    emptySeq := func(yield func(string) bool) {
    // no elements yielded
    }
    idx := it.IndexOf(emptySeq, "anything")
    // idx: -1 (sequence is empty)
    Prototype:
    func IndexOf[T comparable](collection iter.Seq[T], element T) int
  • Returns the index at which the last occurrence of a value is found in the sequence, or -1 if the value is not found.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(10)
    _ = yield(20)
    _ = yield(30)
    _ = yield(20)
    }
    idx := it.LastIndexOf(seq, 20)
    // idx == 3
    seq := func(yield func(string) bool) {
    _ = yield("apple")
    _ = yield("banana")
    _ = yield("cherry")
    }
    idx := it.LastIndexOf(seq, "orange")
    // idx == -1
    Prototype:
    func LastIndexOf[T comparable](collection iter.Seq[T], element T) int
  • Returns true if the collection has the specified prefix. The prefix can be specified as multiple arguments.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(1)
    _ = yield(2)
    _ = yield(3)
    _ = yield(4)
    }
    hasPrefix := it.HasPrefix(seq, 1, 2)
    // hasPrefix == true
    seq := func(yield func(string) bool) {
    _ = yield("hello")
    _ = yield("world")
    }
    hasPrefix := it.HasPrefix(seq, "hello")
    // hasPrefix == true
    seq := func(yield func(int) bool) {
    _ = yield(1)
    _ = yield(2)
    _ = yield(3)
    }
    hasPrefix := it.HasPrefix(seq, 2, 3)
    // hasPrefix == false
    Prototype:
    func HasPrefix[T comparable](collection iter.Seq[T], prefix ...T) bool
  • Returns true if the collection has the specified suffix. The suffix can be specified as multiple arguments.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(1)
    _ = yield(2)
    _ = yield(3)
    _ = yield(4)
    }
    hasSuffix := it.HasSuffix(seq, 3, 4)
    // hasSuffix == true
    seq := func(yield func(string) bool) {
    _ = yield("hello")
    _ = yield("world")
    }
    hasSuffix := it.HasSuffix(seq, "world")
    // hasSuffix == true
    seq := func(yield func(int) bool) {
    _ = yield(1)
    _ = yield(2)
    _ = yield(3)
    }
    hasSuffix := it.HasSuffix(seq, 1, 2)
    // hasSuffix == false
    Prototype:
    func HasSuffix[T comparable](collection iter.Seq[T], suffix ...T) bool
  • Counts the number of elements in the collection that satisfy the predicate.

    result := it.CountBy(it.Range(1, 11), func(item int) bool {
    return item%2 == 0
    })
    // 5
    Variant:
    Prototype:
    func CountBy[T any](collection iter.Seq[T], predicate func(item T) bool) int
  • Searches for an element in a sequence based on a predicate function. Returns the element and true if found, zero value and false if not found.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(10)
    _ = yield(20)
    _ = yield(30)
    _ = yield(40)
    }
    found, ok := it.Find(seq, func(x int) bool {
    return x > 25
    })
    // found == 30, ok == true
    seq := func(yield func(string) bool) {
    _ = yield("apple")
    _ = yield("banana")
    _ = yield("cherry")
    }
    found, ok := it.Find(seq, func(s string) bool {
    return len(s) > 10
    })
    // found == "", ok == false (no element longer than 10 chars)
    Prototype:
    func Find[T any](collection iter.Seq[T], predicate func(item T) bool) (T, bool)
  • Searches for an element based on a predicate and returns the element, its index, and true if found. Returns zero value, -1, and false if not found.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(10)
    _ = yield(20)
    _ = yield(30)
    _ = yield(40)
    }
    found, index, ok := it.FindIndexOf(seq, func(x int) bool {
    return x > 25
    })
    // found == 30, index == 2, ok == true
    seq := func(yield func(string) bool) {
    _ = yield("apple")
    _ = yield("banana")
    _ = yield("cherry")
    }
    found, index, ok := it.FindIndexOf(seq, func(s string) bool {
    return s == "orange"
    })
    // found == "", index == -1, ok == false
    Prototype:
    func FindIndexOf[T any](collection iter.Seq[T], predicate func(item T) bool) (T, int, bool)
  • Searches for the last element matching a predicate and returns the element, its index, and true if found. Returns zero value, -1, and false if not found.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(10)
    _ = yield(20)
    _ = yield(30)
    _ = yield(20)
    _ = yield(40)
    }
    found, index, ok := it.FindLastIndexOf(seq, func(x int) bool {
    return x == 20
    })
    // found == 20, index == 3, ok == true
    seq := func(yield func(string) bool) {
    _ = yield("apple")
    _ = yield("banana")
    _ = yield("cherry")
    }
    found, index, ok := it.FindLastIndexOf(seq, func(s string) bool {
    return len(s) > 10
    })
    // found == "", index == -1, ok == false
    Prototype:
    func FindLastIndexOf[T any](collection iter.Seq[T], predicate func(item T) bool) (T, int, bool)
  • Searches for an element using a predicate or returns a fallback value if not found.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(10)
    _ = yield(20)
    _ = yield(30)
    _ = yield(40)
    }
    result := it.FindOrElse(seq, 99, func(x int) bool {
    return x > 25
    })
    // result == 30
    seq := func(yield func(string) bool) {
    _ = yield("apple")
    _ = yield("banana")
    _ = yield("cherry")
    }
    result := it.FindOrElse(seq, "unknown", func(s string) bool {
    return len(s) > 10
    })
    // result == "unknown" (fallback value)
    Prototype:
    func FindOrElse[T any](collection iter.Seq[T], fallback T, predicate func(item T) bool) T
  • Returns a sequence with elements that appear only once in the original collection (duplicates are removed).

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(1)
    _ = yield(2)
    _ = yield(2)
    _ = yield(3)
    _ = yield(4)
    _ = yield(4)
    }
    uniqueSeq := it.FindUniques(seq)
    var result []int
    for v := range uniqueSeq {
    result = append(result, v)
    }
    // result contains 1, 3 (elements that appear only once)
    seq := func(yield func(string) bool) {
    _ = yield("apple")
    _ = yield("banana")
    _ = yield("apple")
    _ = yield("cherry")
    }
    uniqueSeq := it.FindUniques(seq)
    var result []string
    for v := range uniqueSeq {
    result = append(result, v)
    }
    // result contains "banana", "cherry" (unique elements)
    Prototype:
    func FindUniques[T comparable, I ~func(func(T) bool)](collection I) I
  • Returns the first occurrence of each duplicated element in the collection (elements that appear more than once).

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(1)
    _ = yield(2)
    _ = yield(2)
    _ = yield(3)
    _ = yield(4)
    _ = yield(4)
    _ = yield(4)
    }
    dupSeq := it.FindDuplicates(seq)
    var result []int
    for v := range dupSeq {
    result = append(result, v)
    }
    // result contains 2, 4 (first occurrence of each duplicated element)
    seq := func(yield func(string) bool) {
    _ = yield("apple")
    _ = yield("banana")
    _ = yield("apple")
    _ = yield("cherry")
    _ = yield("banana")
    }
    dupSeq := it.FindDuplicates(seq)
    var result []string
    for v := range dupSeq {
    result = append(result, v)
    }
    // result contains "apple", "banana" (duplicated elements)
    Prototype:
    func FindDuplicates[T comparable, I ~func(func(T) bool)](collection I) I
  • Searches the minimum value of a collection. Returns the smallest element found.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(5)
    _ = yield(2)
    _ = yield(8)
    _ = yield(1)
    _ = yield(9)
    }
    min := it.Min(seq)
    // min == 1
    seq := func(yield func(string) bool) {
    _ = yield("zebra")
    _ = yield("apple")
    _ = yield("banana")
    }
    min := it.Min(seq)
    // min == "apple" (lexicographically smallest)
    Prototype:
    func Min[T constraints.Ordered](collection iter.Seq[T]) T
  • Searches the maximum value of a collection. Returns the largest element found.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(5)
    _ = yield(2)
    _ = yield(8)
    _ = yield(1)
    _ = yield(9)
    }
    max := it.Max(seq)
    // max == 9
    seq := func(yield func(string) bool) {
    _ = yield("zebra")
    _ = yield("apple")
    _ = yield("banana")
    }
    max := it.Max(seq)
    // max == "zebra" (lexicographically largest)
    Prototype:
    func Max[T constraints.Ordered](collection iter.Seq[T]) T
  • Returns the first element of a collection and a boolean indicating availability. Returns zero value and false if the collection is empty.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(10)
    _ = yield(20)
    _ = yield(30)
    }
    first, ok := it.First(seq)
    // first == 10, ok == true
    seq := func(yield func(string) bool) {
    // empty sequence
    }
    first, ok := it.First(seq)
    // first == "", ok == false (zero value for string)
    Prototype:
    func First[T any](collection iter.Seq[T]) (T, bool)
  • Returns the last element of a collection and a boolean indicating availability. Returns zero value and false if the collection is empty.

    Examples:

    seq := func(yield func(int) bool) {
    _ = yield(10)
    _ = yield(20)
    _ = yield(30)
    }
    last, ok := it.Last(seq)
    // last == 30, ok == true
    seq := func(yield func(string) bool) {
    // empty sequence
    }
    last, ok := it.Last(seq)
    // last == "", ok == false (zero value for string)
    Prototype:
    func Last[T any](collection iter.Seq[T]) (T, bool)
  • Searches minimum value using a custom comparison function. The comparison function should return true if the first argument is "less than" the second.

    Examples:

    type Person struct {
    Name string
    Age int
    }
    seq := func(yield func(Person) bool) {
    _ = yield(Person{"Alice", 30})
    _ = yield(Person{"Bob", 25})
    _ = yield(Person{"Charlie", 35})
    }
    youngest := it.MinBy(seq, func(a, b Person) bool {
    return a.Age < b.Age
    })
    // youngest == Person{"Bob", 25}
    Prototype:
    func MinBy[T any](collection iter.Seq[T], comparison func(a, b T) bool) T
  • Searches maximum value using a custom comparison function. The comparison function should return true if the first argument is "greater than" the second.

    Examples:

    type Person struct {
    Name string
    Age int
    }
    seq := func(yield func(Person) bool) {
    _ = yield(Person{"Alice", 30})
    _ = yield(Person{"Bob", 25})
    _ = yield(Person{"Charlie", 35})
    }
    oldest := it.MaxBy(seq, func(a, b Person) bool {
    return a.Age > b.Age
    })
    // oldest == Person{"Charlie", 35}
    Prototype:
    func MaxBy[T any](collection iter.Seq[T], comparison func(a, b T) bool) T
  • Returns a random item from collection.

    Example:

    seq := func(yield func(string) bool) {
    _ = yield("apple")
    _ = yield("banana")
    _ = yield("cherry")
    }
    item := it.Sample(seq)
    // item is randomly one of: "apple", "banana", "cherry"

    // Example with integers
    numbers := func(yield func(int) bool) {
    _ = yield(10)
    _ = yield(20)
    _ = yield(30)
    _ = yield(40)
    }
    randomNum := it.Sample(numbers)
    // randomNum is randomly one of: 10, 20, 30, 40

    // Example with empty sequence - returns zero value
    empty := func(yield func(string) bool) {
    // no yields
    }
    emptyResult := it.Sample(empty)
    // emptyResult: "" (zero value for string)

    // Example with single item
    single := func(yield func(int) bool) {
    _ = yield(42)
    }
    singleResult := it.Sample(single)
    // singleResult: 42 (always returns 42 since it's the only option)
    Prototype:
    func Sample[T any](collection iter.Seq[T]) T
  • Returns a random item from collection, using a custom random index generator.

    Example:

    seq := func(yield func(int) bool) {
    _ = yield(1)
    _ = yield(2)
    _ = yield(3)
    }
    // Use custom RNG for predictable results (returns first element)
    item := it.SampleBy(seq, func(max int) int { return 0 })
    // item == 1
    Prototype:
    func SampleBy[T any](collection iter.Seq[T], randomIntGenerator func(int) int) T
  • Searches the minimum value of a collection and returns both the value and its index.

    Returns (zero value, -1) when the collection is empty.
    Will iterate through the entire sequence.

    Examples:

    // Find the minimum value and its index
    numbers := it.Slice([]int{5, 2, 8, 1, 9})
    value, index := it.MinIndex(numbers)
    // value: 1, index: 3

    // With empty collection
    empty := it.Slice([]int{})
    value, index := it.MinIndex(empty)
    // value: 0, index: -1
    Prototype:
    func MinIndex[T constraints.Ordered](collection iter.Seq[T]) (T, int)
  • Searches the minimum value of a collection using a comparison function and returns both the value and its index.

    If several values are equal to the smallest value, returns the first such value.
    Returns (zero value, -1) when the collection is empty.
    Will iterate through the entire sequence.

    Examples:

    // Find the minimum string by length and its index
    words := it.Slice([]string{"apple", "hi", "banana", "ok"})
    value, index := it.MinIndexBy(words, func(a, b string) bool {
    return len(a) < len(b)
    })
    // value: "hi", index: 1

    // Find the minimum person by age and its index
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 35},
    })
    value, index := it.MinIndexBy(people, func(a, b Person) bool {
    return a.Age < b.Age
    })
    // value: {Name: "Bob", Age: 25}, index: 1
    Prototype:
    func MinIndexBy[T any](collection iter.Seq[T], comparison func(a, b T) bool) (T, int)
  • Searches the maximum value of a collection and returns both the value and its index.

    Returns (zero value, -1) when the collection is empty.
    Will iterate through the entire sequence.

    Examples:

    // Find the maximum value and its index
    numbers := it.Slice([]int{5, 2, 8, 1, 9})
    value, index := it.MaxIndex(numbers)
    // value: 9, index: 4

    // With empty collection
    empty := it.Slice([]int{})
    value, index := it.MaxIndex(empty)
    // value: 0, index: -1

    // Find the maximum string alphabetically and its index
    words := it.Slice([]string{"apple", "zebra", "banana", "xylophone"})
    value, index := it.MaxIndex(words)
    // value: "zebra", index: 1
    Prototype:
    func MaxIndex[T constraints.Ordered](collection iter.Seq[T]) (T, int)
  • Searches the maximum value of a collection using a comparison function and returns both the value and its index.

    If several values are equal to the greatest value, returns the first such value.
    Returns (zero value, -1) when the collection is empty.
    Will iterate through the entire sequence.

    Examples:

    // Find the maximum string by length and its index
    words := it.Slice([]string{"apple", "hi", "banana", "xylophone"})
    value, index := it.MaxIndexBy(words, func(a, b string) bool {
    return len(a) > len(b)
    })
    // value: "xylophone", index: 3

    // Find the maximum person by age and its index
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 35},
    })
    value, index := it.MaxIndexBy(people, func(a, b Person) bool {
    return a.Age > b.Age
    })
    // value: {Name: "Charlie", Age: 35}, index: 2

    // Find the maximum number by absolute value and its index
    numbers := it.Slice([]int{-5, 2, -8, 1})
    value, index := it.MaxIndexBy(numbers, func(a, b int) bool {
    return abs(a) > abs(b)
    })
    // value: -8, index: 2
    Prototype:
    func MaxIndexBy[T any](collection iter.Seq[T], comparison func(a, b T) bool) (T, int)
  • Searches for the earliest (minimum) time.Time in a collection.

    Returns zero value when the collection is empty.
    Will iterate through the entire sequence.

    Examples:

    import "time"

    // Find the earliest time from a collection
    times := it.Slice([]time.Time{
    time.Date(2023, 5, 15, 10, 0, 0, 0, time.UTC),
    time.Date(2023, 3, 20, 14, 30, 0, 0, time.UTC),
    time.Date(2023, 8, 1, 9, 15, 0, 0, time.UTC),
    })
    earliest := it.Earliest(times)
    // earliest: 2023-03-20 14:30:00 +0000 UTC

    // With empty collection
    empty := it.Slice([]time.Time{})
    earliest := it.Earliest(empty)
    // earliest: 0001-01-01 00:00:00 +0000 UTC (zero value)

    // Find earliest from parsed times
    times := it.Slice([]time.Time{
    time.Parse(time.RFC3339, "2023-01-01T12:00:00Z"),
    time.Parse(time.RFC3339, "2023-01-01T10:00:00Z"),
    time.Parse(time.RFC3339, "2023-01-01T14:00:00Z"),
    })
    earliest := it.Earliest(times)
    // earliest: 2023-01-01 10:00:00 +0000 UTC
    Prototype:
    func Earliest(times iter.Seq[time.Time]) time.Time
  • Searches for the element with the earliest time using a transform function.

    Returns zero value when the collection is empty.
    Will iterate through the entire sequence.

    Examples:

    import "time"

    type Event struct {
    Name string
    Time time.Time
    }

    // Find the earliest event by time
    events := it.Slice([]Event{
    {"Meeting", time.Date(2023, 5, 15, 10, 0, 0, 0, time.UTC)},
    {"Lunch", time.Date(2023, 5, 15, 12, 0, 0, 0, time.UTC)},
    {"Breakfast", time.Date(2023, 5, 15, 8, 0, 0, 0, time.UTC)},
    })
    earliest := it.EarliestBy(events, func(e Event) time.Time {
    return e.Time
    })
    // earliest: {Name: "Breakfast", Time: 2023-05-15 08:00:00 +0000 UTC}

    // Find the earliest task by deadline
    type Task struct {
    ID int
    Deadline time.Time
    }
    tasks := it.Slice([]Task{
    {1, time.Date(2023, 6, 1, 0, 0, 0, 0, time.UTC)},
    {2, time.Date(2023, 5, 15, 0, 0, 0, 0, time.UTC)},
    {3, time.Date(2023, 7, 1, 0, 0, 0, 0, time.UTC)},
    })
    earliest := it.EarliestBy(tasks, func(t Task) time.Time {
    return t.Deadline
    })
    // earliest: {ID: 2, Deadline: 2023-05-15 00:00:00 +0000 UTC}
    Prototype:
    func EarliestBy[T any](collection iter.Seq[T], transform func(item T) time.Time) T
  • Searches for the latest (maximum) time.Time in a collection.

    Returns zero value when the collection is empty.
    Will iterate through the entire sequence.

    Examples:

    import "time"

    // Find the latest time from a collection
    times := it.Slice([]time.Time{
    time.Date(2023, 5, 15, 10, 0, 0, 0, time.UTC),
    time.Date(2023, 3, 20, 14, 30, 0, 0, time.UTC),
    time.Date(2023, 8, 1, 9, 15, 0, 0, time.UTC),
    })
    latest := it.Latest(times)
    // latest: 2023-08-01 09:15:00 +0000 UTC

    // With empty collection
    empty := it.Slice([]time.Time{})
    latest := it.Latest(empty)
    // latest: 0001-01-01 00:00:00 +0000 UTC (zero value)

    // Find latest from parsed times
    times := it.Slice([]time.Time{
    time.Parse(time.RFC3339, "2023-01-01T12:00:00Z"),
    time.Parse(time.RFC3339, "2023-01-01T10:00:00Z"),
    time.Parse(time.RFC3339, "2023-01-01T14:00:00Z"),
    })
    latest := it.Latest(times)
    // latest: 2023-01-01 14:00:00 +0000 UTC

    // Find latest log entry timestamp
    logs := it.Slice([]time.Time{
    time.Now().Add(-2 * time.Hour),
    time.Now().Add(-1 * time.Hour),
    time.Now(),
    })
    latest := it.Latest(logs)
    // latest: current time
    Prototype:
    func Latest(times iter.Seq[time.Time]) time.Time
  • Searches for the element with the latest time using a transform function.

    Returns zero value when the collection is empty.
    Will iterate through the entire sequence.

    Examples:

    import "time"

    type Event struct {
    Name string
    Time time.Time
    }

    // Find the latest event by time
    events := it.Slice([]Event{
    {"Meeting", time.Date(2023, 5, 15, 10, 0, 0, 0, time.UTC)},
    {"Lunch", time.Date(2023, 5, 15, 12, 0, 0, 0, time.UTC)},
    {"Breakfast", time.Date(2023, 5, 15, 8, 0, 0, 0, time.UTC)},
    })
    latest := it.LatestBy(events, func(e Event) time.Time {
    return e.Time
    })
    // latest: {Name: "Lunch", Time: 2023-05-15 12:00:00 +0000 UTC}

    // Find the latest task by deadline
    type Task struct {
    ID int
    Deadline time.Time
    }
    tasks := it.Slice([]Task{
    {1, time.Date(2023, 6, 1, 0, 0, 0, 0, time.UTC)},
    {2, time.Date(2023, 5, 15, 0, 0, 0, 0, time.UTC)},
    {3, time.Date(2023, 7, 1, 0, 0, 0, 0, time.UTC)},
    })
    latest := it.LatestBy(tasks, func(t Task) time.Time {
    return t.Deadline
    })
    // latest: {ID: 3, Deadline: 2023-07-01 00:00:00 +0000 UTC}

    // Find the most recent activity
    type Activity struct {
    User string
    Action string
    Time time.Time
    }
    activities := it.Slice([]Activity{
    {"alice", "login", time.Now().Add(-24 * time.Hour)},
    {"bob", "logout", time.Now().Add(-12 * time.Hour)},
    {"alice", "post", time.Now().Add(-1 * time.Hour)},
    })
    latest := it.LatestBy(activities, func(a Activity) time.Time {
    return a.Time
    })
    // latest: {User: "alice", Action: "post", Time: 1 hour ago}
    Prototype:
    func LatestBy[T any](collection iter.Seq[T], transform func(item T) time.Time) T
  • Returns the first element of a collection or zero value if empty.

    Will iterate at most once.

    Examples:

    // Get the first element or zero value
    numbers := it.Slice([]int{5, 2, 8, 1, 9})
    first := it.FirstOrEmpty(numbers)
    // first: 5

    // With empty collection
    empty := it.Slice([]int{})
    first := it.FirstOrEmpty(empty)
    // first: 0 (zero value for int)

    // With strings
    words := it.Slice([]string{"hello", "world", "go"})
    first := it.FirstOrEmpty(words)
    // first: "hello"

    emptyWords := it.Slice([]string{})
    first := it.FirstOrEmpty(emptyWords)
    // first: "" (zero value for string)

    // With structs
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    })
    first := it.FirstOrEmpty(people)
    // first: {Name: "Alice", Age: 30}

    emptyPeople := it.Slice([]Person{})
    first := it.FirstOrEmpty(emptyPeople)
    // first: {Name: "", Age: 0} (zero value for Person)
    Prototype:
    func FirstOrEmpty[T any](collection iter.Seq[T]) T
  • Returns the first element of a collection or the fallback value if empty.

    Will iterate at most once.

    Examples:

    // Get the first element or fallback value
    numbers := it.Slice([]int{5, 2, 8, 1, 9})
    first := it.FirstOr(numbers, 42)
    // first: 5

    // With empty collection
    empty := it.Slice([]int{})
    first := it.FirstOr(empty, 42)
    // first: 42 (fallback value)

    // With strings
    words := it.Slice([]string{"hello", "world", "go"})
    first := it.FirstOr(words, "fallback")
    // first: "hello"

    emptyWords := it.Slice([]string{})
    first := it.FirstOr(emptyWords, "fallback")
    // first: "fallback"

    // With structs
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    })
    first := it.FirstOr(people, Person{Name: "Default", Age: 0})
    // first: {Name: "Alice", Age: 30}

    emptyPeople := it.Slice([]Person{})
    first := it.FirstOr(emptyPeople, Person{Name: "Default", Age: 0})
    // first: {Name: "Default", Age: 0} (fallback value)

    // Using with pointers
    pointers := it.Slice([]*int{ptr(5), ptr(10), ptr(15)})
    first := it.FirstOr(pointers, nil)
    // first: pointer to 5

    emptyPointers := it.Slice([]*int{})
    first := it.FirstOr(emptyPointers, nil)
    // first: nil (fallback value)
    Prototype:
    func FirstOr[T any](collection iter.Seq[T], fallback T) T
  • Returns the last element of a collection or zero value if empty.

    Will iterate through the entire sequence.

    Examples:

    // Get the last element or zero value
    numbers := it.Slice([]int{5, 2, 8, 1, 9})
    last := it.LastOrEmpty(numbers)
    // last: 9

    // With empty collection
    empty := it.Slice([]int{})
    last := it.LastOrEmpty(empty)
    // last: 0 (zero value for int)

    // With strings
    words := it.Slice([]string{"hello", "world", "go"})
    last := it.LastOrEmpty(words)
    // last: "go"

    emptyWords := it.Slice([]string{})
    last := it.LastOrEmpty(emptyWords)
    // last: "" (zero value for string)

    // With structs
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    })
    last := it.LastOrEmpty(people)
    // last: {Name: "Bob", Age: 25}

    emptyPeople := it.Slice([]Person{})
    last := it.LastOrEmpty(emptyPeople)
    // last: {Name: "", Age: 0} (zero value for Person)

    // With single element
    single := it.Slice([]int{42})
    last := it.LastOrEmpty(single)
    // last: 42
    Prototype:
    func LastOrEmpty[T any](collection iter.Seq[T]) T
  • Returns the last element of a collection or the fallback value if empty.

    Will iterate through the entire sequence.

    Examples:

    // Get the last element or fallback value
    numbers := it.Slice([]int{5, 2, 8, 1, 9})
    last := it.LastOr(numbers, 42)
    // last: 9

    // With empty collection
    empty := it.Slice([]int{})
    last := it.LastOr(empty, 42)
    // last: 42 (fallback value)

    // With strings
    words := it.Slice([]string{"hello", "world", "go"})
    last := it.LastOr(words, "fallback")
    // last: "go"

    emptyWords := it.Slice([]string{})
    last := it.LastOr(emptyWords, "fallback")
    // last: "fallback"

    // With structs
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    })
    last := it.LastOr(people, Person{Name: "Default", Age: 0})
    // last: {Name: "Bob", Age: 25}

    emptyPeople := it.Slice([]Person{})
    last := it.LastOr(emptyPeople, Person{Name: "Default", Age: 0})
    // last: {Name: "Default", Age: 0} (fallback value)

    // With single element
    single := it.Slice([]int{42})
    last := it.LastOr(single, 99)
    // last: 42

    // Using with nil pointer fallback
    values := it.Slice([]*string{ptr("hello"), ptr("world")})
    last := it.LastOr(values, nil)
    // last: pointer to "world"

    emptyValues := it.Slice([]*string{})
    last := it.LastOr(emptyValues, nil)
    // last: nil (fallback value)
    Prototype:
    func LastOr[T any](collection iter.Seq[T], fallback T) T
  • Returns the element at index nth of collection. Returns an error when nth is out of bounds.

    Will iterate n times through the sequence.

    Examples:

    // Get element at specific index
    numbers := it.Slice([]int{5, 2, 8, 1, 9})
    element, err := it.Nth(numbers, 2)
    // element: 8, err: nil

    // Get first element (index 0)
    first, err := it.Nth(numbers, 0)
    // first: 5, err: nil

    // Get last element
    last, err := it.Nth(numbers, 4)
    // last: 9, err: nil

    // Out of bounds - negative
    _, err := it.Nth(numbers, -1)
    // err: nth: -1 out of bounds

    // Out of bounds - too large
    _, err := it.Nth(numbers, 10)
    // err: nth: 10 out of bounds

    // With strings
    words := it.Slice([]string{"hello", "world", "go", "lang"})
    element, err := it.Nth(words, 1)
    // element: "world", err: nil

    // With different integer types
    numbers := it.Slice([]int{1, 2, 3, 4, 5})
    element, err := it.Nth(numbers, int8(3))
    // element: 4, err: nil

    // 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},
    })
    element, err := it.Nth(people, 1)
    // element: {Name: "Bob", Age: 25}, err: nil
    Prototype:
    func Nth[T any, N constraints.Integer](collection iter.Seq[T], nth N) (T, error)
  • Returns the element at index nth of collection. If nth is out of bounds, returns the fallback value instead of an error.

    Will iterate n times through the sequence.

    Examples:

    // Get element at specific index
    numbers := it.Slice([]int{5, 2, 8, 1, 9})
    element := it.NthOr(numbers, 2, 42)
    // element: 8

    // Get first element (index 0)
    first := it.NthOr(numbers, 0, 42)
    // first: 5

    // Get last element
    last := it.NthOr(numbers, 4, 42)
    // last: 9

    // Out of bounds - negative, returns fallback
    element := it.NthOr(numbers, -1, 42)
    // element: 42 (fallback)

    // Out of bounds - too large, returns fallback
    element := it.NthOr(numbers, 10, 42)
    // element: 42 (fallback)

    // With strings
    words := it.Slice([]string{"hello", "world", "go", "lang"})
    element := it.NthOr(words, 1, "fallback")
    // element: "world"

    // Out of bounds with string fallback
    element := it.NthOr(words, 10, "fallback")
    // element: "fallback"

    // With structs
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    })
    fallback := Person{Name: "Default", Age: 0}
    element := it.NthOr(people, 1, fallback)
    // element: {Name: "Bob", Age: 25}

    // Out of bounds with struct fallback
    element := it.NthOr(people, 5, fallback)
    // element: {Name: "Default", Age: 0}

    // With different integer types
    numbers := it.Slice([]int{1, 2, 3, 4, 5})
    element := it.NthOr(numbers, int8(3), 99)
    // element: 4
    Prototype:
    func NthOr[T any, N constraints.Integer](collection iter.Seq[T], nth N, fallback T) T
  • Returns the element at index nth of collection. If nth is out of bounds, returns the zero value (empty value) for that type.

    Will iterate n times through the sequence.

    Examples:

    // Get element at specific index
    numbers := it.Slice([]int{5, 2, 8, 1, 9})
    element := it.NthOrEmpty(numbers, 2)
    // element: 8

    // Get first element (index 0)
    first := it.NthOrEmpty(numbers, 0)
    // first: 5

    // Get last element
    last := it.NthOrEmpty(numbers, 4)
    // last: 9

    // Out of bounds - negative, returns zero value
    element := it.NthOrEmpty(numbers, -1)
    // element: 0 (zero value for int)

    // Out of bounds - too large, returns zero value
    element := it.NthOrEmpty(numbers, 10)
    // element: 0 (zero value for int)

    // With strings
    words := it.Slice([]string{"hello", "world", "go", "lang"})
    element := it.NthOrEmpty(words, 1)
    // element: "world"

    // Out of bounds with string - returns empty string
    element := it.NthOrEmpty(words, 10)
    // element: "" (zero value for string)

    // With structs
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    })
    element := it.NthOrEmpty(people, 1)
    // element: {Name: "Bob", Age: 25}

    // Out of bounds with struct - returns zero value
    element := it.NthOrEmpty(people, 5)
    // element: {Name: "", Age: 0} (zero value for Person)

    // With pointers - returns nil when out of bounds
    values := it.Slice([]*string{ptr("hello"), ptr("world")})
    element := it.NthOrEmpty(values, 1)
    // element: pointer to "world"

    // Out of bounds with pointer - returns nil
    element := it.NthOrEmpty(values, 5)
    // element: nil (zero value for *string)

    // With different integer types
    numbers := it.Slice([]int{1, 2, 3, 4, 5})
    element := it.NthOrEmpty(numbers, int8(3))
    // element: 4
    Prototype:
    func NthOrEmpty[T any, N constraints.Integer](collection iter.Seq[T], nth N) T
  • Returns N random unique items from collection.

    Will iterate through the entire sequence and allocate a slice large enough to hold all elements.
    Long input sequences can cause excessive memory usage.

    Examples:

    // Get 3 random unique items from collection
    numbers := it.Slice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
    samples := it.Samples(numbers, 3)
    // samples: sequence of 3 random unique numbers from 1-10

    // Get all items if count equals collection size
    numbers := it.Slice([]int{1, 2, 3, 4, 5})
    samples := it.Samples(numbers, 5)
    // samples: sequence containing all 5 numbers in random order

    // Get fewer items than collection size
    numbers := it.Slice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
    samples := it.Samples(numbers, 3)
    // samples: sequence of 3 random unique numbers

    // With strings
    words := it.Slice([]string{"apple", "banana", "cherry", "date", "elderberry"})
    samples := it.Samples(words, 2)
    // samples: sequence of 2 random unique words

    // 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},
    })
    samples := it.Samples(people, 3)
    // samples: sequence of 3 random unique people

    // Count larger than collection size - returns all items in random order
    numbers := it.Slice([]int{1, 2, 3})
    samples := it.Samples(numbers, 10)
    // samples: sequence of all 3 numbers in random order

    // Zero count - returns empty sequence
    numbers := it.Slice([]int{1, 2, 3, 4, 5})
    samples := it.Samples(numbers, 0)
    // samples: empty sequence

    // Negative count - returns empty sequence
    numbers := it.Slice([]int{1, 2, 3, 4, 5})
    samples := it.Samples(numbers, -1)
    // samples: empty sequence
    Prototype:
    func Samples[T any, I ~func(func(T) bool)](collection I, count int) I
  • Returns N random unique items from collection, using randomIntGenerator as the random index generator.

    Will iterate through the entire sequence and allocate a slice large enough to hold all elements.
    Long input sequences can cause excessive memory usage.

    Examples:

    import (
    "math/rand"
    "time"
    )

    // Use default random generator with seed
    rng := rand.New(rand.NewSource(time.Now().UnixNano()))

    // Get 3 random unique items with custom random generator
    numbers := it.Slice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
    samples := it.SamplesBy(numbers, 3, rng.Intn)
    // samples: sequence of 3 random unique numbers

    // Use deterministic random generator for testing
    deterministicRng := rand.New(rand.NewSource(42))
    samples := it.SamplesBy(numbers, 3, deterministicRng.Intn)
    // samples: predictable sequence of 3 unique numbers

    // With strings
    words := it.Slice([]string{"apple", "banana", "cherry", "date", "elderberry"})
    samples := it.SamplesBy(words, 2, rng.Intn)
    // samples: sequence of 2 random unique words

    // 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},
    })
    samples := it.SamplesBy(people, 3, rng.Intn)
    // samples: sequence of 3 random unique people

    // Custom random function that biases towards certain items
    biasedRandom := func(max int) int {
    // Bias towards first half of collection
    return rng.Intn(max/2 + 1)
    }
    samples := it.SamplesBy(numbers, 3, biasedRandom)
    // samples: sequence of 3 random unique numbers, biased towards lower indices

    // With zero-based modulo function (wraps around)
    moduloRandom := func(max int) int {
    return rng.Intn(max*3) % max
    }
    samples := it.SamplesBy(numbers, 3, moduloRandom)
    // samples: sequence of 3 random unique numbers

    // Test with deterministic function
    deterministicFunc := func(max int) int {
    return (max - 1) / 2 // Always return middle index
    }
    samples := it.SamplesBy(numbers, 1, deterministicFunc)
    // samples: sequence with single element from middle
    Prototype:
    func SamplesBy[T any, I ~func(func(T) bool)](collection I, count int, randomIntGenerator func(int) int) I
  • Returns a sequence with all the elements that appear in the collection only once, based on a transform function.

    The order of result values is determined by the order they occur in the collection. A transform function is
    invoked for each element in the sequence to generate the criterion by which uniqueness is computed.
    Will iterate through the entire sequence before yielding and allocate a map large enough to hold all distinct transformed elements.
    Long heterogeneous input sequences can cause excessive memory usage.

    Examples:

    // Find unique people by age
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 30}, // Same age as Alice, so Alice is not unique
    {Name: "Diana", Age: 28},
    })
    uniques := it.FindUniquesBy(people, func(p Person) int { return p.Age })
    // uniques: sequence with Bob (age 25) and Diana (age 28)

    // Find unique strings by length
    words := it.Slice([]string{"hello", "world", "hi", "go", "bye"})
    uniques := it.FindUniquesBy(words, func(s string) int { return len(s) })
    // uniques: sequence with words of unique lengths
    // "hello" (5), "world" (5) - not unique due to same length
    // "hi" (2), "go" (2), "bye" (3) - "bye" is unique (length 3)

    // Find unique items by first letter
    items := it.Slice([]string{"apple", "apricot", "banana", "blueberry", "cherry"})
    uniques := it.FindUniquesBy(items, func(s string) byte { return s[0] })
    // uniques: sequence with "cherry" (only word starting with 'c')

    // Find unique numbers by modulo
    numbers := it.Slice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
    uniques := it.FindUniquesBy(numbers, func(n int) int { return n % 3 })
    // uniques: sequence with numbers that have unique remainders when divided by 3

    // Find unique structs by composite key
    type Order struct {
    CustomerID string
    ProductID string
    }
    orders := it.Slice([]Order{
    {CustomerID: "A", ProductID: "1"},
    {CustomerID: "A", ProductID: "2"},
    {CustomerID: "B", ProductID: "1"}, // Same customer as first orders
    {CustomerID: "C", ProductID: "3"},
    })
    uniques := it.FindUniquesBy(orders, func(o Order) string { return o.CustomerID })
    // uniques: sequence with Order{CustomerID: "C", ProductID: "3"} only

    // Find unique items by case-insensitive comparison
    words := it.Slice([]string{"Hello", "hello", "WORLD", "world", "Go"})
    uniques := it.FindUniquesBy(words, func(s string) string { return strings.ToLower(s) })
    // uniques: sequence with "Go" only (others have case-insensitive duplicates)

    // Find unique dates by year-month
    import "time"
    dates := it.Slice([]time.Time{
    time.Date(2023, 1, 15, 0, 0, 0, 0, time.UTC),
    time.Date(2023, 1, 20, 0, 0, 0, 0, time.UTC), // Same month as first
    time.Date(2023, 2, 10, 0, 0, 0, 0, time.UTC),
    time.Date(2022, 1, 5, 0, 0, 0, 0, time.UTC), // Different year
    })
    uniques := it.FindUniquesBy(dates, func(t time.Time) string {
    return fmt.Sprintf("%d-%02d", t.Year(), t.Month())
    })
    // uniques: sequence with dates from unique year-month combinations
    Prototype:
    func FindUniquesBy[T any, U comparable, I ~func(func(T) bool)](collection I, transform func(item T) U) I
  • Returns a sequence with the first occurrence of each duplicated element in the collection, based on a transform function.

    The order of result values is determined by the order duplicates occur in the sequence. A transform function is
    invoked for each element in the sequence to generate the criterion by which uniqueness is computed.
    Will allocate a map large enough to hold all distinct transformed elements.
    Long heterogeneous input sequences can cause excessive memory usage.

    Examples:

    // Find duplicate people by age
    type Person struct {
    Name string
    Age int
    }
    people := it.Slice([]Person{
    {Name: "Alice", Age: 30},
    {Name: "Bob", Age: 25},
    {Name: "Charlie", Age: 30}, // Same age as Alice - Alice is returned
    {Name: "Diana", Age: 30}, // Same age as Alice - already marked as duplicate
    {Name: "Eve", Age: 25}, // Same age as Bob - Bob is returned
    })
    duplicates := it.FindDuplicatesBy(people, func(p Person) int { return p.Age })
    // duplicates: sequence with Alice (age 30) and Bob (age 25)

    // Find duplicate strings by length
    words := it.Slice([]string{"hello", "world", "hi", "go", "bye", "yes"})
    duplicates := it.FindDuplicatesBy(words, func(s string) int { return len(s) })
    // duplicates: sequence with "hello" (length 5, also "world" has length 5)
    // and "hi" (length 2, also "go", "yes" have length 2)

    // Find duplicate items by first letter
    items := it.Slice([]string{"apple", "apricot", "banana", "blueberry", "cherry", "cranberry"})
    duplicates := it.FindDuplicatesBy(items, func(s string) byte { return s[0] })
    // duplicates: sequence with "apple" (starts with 'a', also "apricot"),
    // "banana" (starts with 'b', also "blueberry"),
    // "cherry" (starts with 'c', also "cranberry")

    // Find duplicate numbers by modulo
    numbers := it.Slice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12})
    duplicates := it.FindDuplicatesBy(numbers, func(n int) int { return n % 3 })
    // duplicates: sequence with 1, 2, 3 (remainders 1, 2, 0 appear multiple times)

    // Find duplicate structs by composite key
    type Order struct {
    CustomerID string
    ProductID string
    }
    orders := it.Slice([]Order{
    {CustomerID: "A", ProductID: "1"},
    {CustomerID: "A", ProductID: "2"},
    {CustomerID: "B", ProductID: "1"}, // Same customer as first
    {CustomerID: "C", ProductID: "3"},
    {CustomerID: "A", ProductID: "3"}, // Same customer as first two
    })
    duplicates := it.FindDuplicatesBy(orders, func(o Order) string { return o.CustomerID })
    // duplicates: sequence with first order {CustomerID: "A", ProductID: "1"}

    // Find duplicate items by case-insensitive comparison
    words := it.Slice([]string{"Hello", "hello", "WORLD", "world", "Go", "GO", "go"})
    duplicates := it.FindDuplicatesBy(words, func(s string) string { return strings.ToLower(s) })
    // duplicates: sequence with "Hello", "WORLD", "Go" (first occurrences of each case-insensitive duplicate)

    // Find duplicate dates by year-month
    import "time"
    dates := it.Slice([]time.Time{
    time.Date(2023, 1, 15, 0, 0, 0, 0, time.UTC),
    time.Date(2023, 1, 20, 0, 0, 0, 0, time.UTC), // Same month as first
    time.Date(2023, 2, 10, 0, 0, 0, 0, time.UTC),
    time.Date(2022, 1, 5, 0, 0, 0, 0, time.UTC), // Different year
    time.Date(2023, 2, 25, 0, 0, 0, 0, time.UTC), // Same month as third
    })
    duplicates := it.FindDuplicatesBy(dates, func(t time.Time) string {
    return fmt.Sprintf("%d-%02d", t.Year(), t.Month())
    })
    // duplicates: sequence with first January date and first February date

    // Find duplicate emails by domain
    type Email struct {
    Address string
    }
    emails := it.Slice([]Email{
    {Address: "[email protected]"},
    {Address: "[email protected]"}, // Same domain as first
    {Address: "[email protected]"},
    {Address: "[email protected]"}, // Same domain as first two
    {Address: "[email protected]"},
    })
    duplicates := it.FindDuplicatesBy(emails, func(e Email) string {
    parts := strings.Split(e.Address, "@")
    if len(parts) > 1 {
    return parts[1]
    }
    return ""
    })
    // duplicates: sequence with first email {Address: "[email protected]"}
    Prototype:
    func FindDuplicatesBy[T any, U comparable, I ~func(func(T) bool)](collection I, transform func(item T) U) I