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 - Find helpersโ€‹

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

  • 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