enumerable

package module
v1.25.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 17, 2025 License: MIT Imports: 0 Imported by: 0

README

enumerable: Lazy, Generic Iterators for Go

GoDoc GitHub go.mod Go version of a Go module GitHub release

Тесты

enumerable is a Go library for functional-style data processing using generics and lazy iterators.

It lets you filter, transform, and aggregate data in a clean, readable way — without for loops or intermediate slices. Operations are evaluated lazily, meaning no unnecessary allocations or eager processing, making it efficient even for large or streaming datasets.

Composable. Lazy. Generic. Type-safe.


✨ Features

  • Functional pipeline operators: Chainable methods like Where, Select, Take, Skip, First, Any, All, Count, and more - all evaluated lazily and fully type-safe.
  • Lazy iterators — data is processed on-demand.
  • Generics (Go 1.18+) — type safety without type casting.
  • Method chaining — fluent, readable APIs.
  • Efficiency — minimal allocations, suitable for large datasets.
  • Nil-safe operations — methods safely handle nil sequences without panics.
  • Two enumerator typesEnumeratorAny[T any] for any type and Enumerator[T comparable] for comparable types with enhanced functionality.
  • Set operations for comparable types — additional methods like Distinct, Except, Intersect, and Union available when working with comparable data.

🚀 Installation

Use go get to add the library to your project:

go get github.com/ahatornn/enumerable

⚖️ Comparison: Enumerable vs Vanilla Go

Let’s say you want to: Merge two slices, keep numbers greater than 50, skip the first 3, and take the next 2.

✅ Using enumerable
nums1 := []int{10, 20, 60, 70}
nums2 := []int{30, 40, 80, 90, 100}

result := enumerable.FromSlice(nums1).
    Union(enumerable.FromSlice(nums2)).
    Where(func(x int) bool { return x > 50 }).
    Skip(3).
    Take(2).
    ToSlice()

fmt.Println(result) // Result: [90 100]
🛠 Without the library (manual)
nums1 := []int{10, 20, 60, 70}
nums2 := []int{30, 40, 80, 90, 100}

seen := make(map[int]bool)
var union []int

for _, x := range nums1 {
    if !seen[x] {
        seen[x] = true
        union = append(union, x)
    }
}
for _, x := range nums2 {
    if !seen[x] {
        seen[x] = true
        union = append(union, x)
    }
}

var filtered []int
for _, x := range union {
    if x > 50 {
        filtered = append(filtered, x)
    }
}

var result []int
countSkipped := 0
countTaken := 0
for _, x := range filtered {
    if countSkipped < 3 {
        countSkipped++
        continue
    }
    if countTaken < 2 {
        result = append(result, x)
        countTaken++
    } else {
        break
    }
}

⚙️ Methods

🌱 Creation Methods

Initialize new sequences from scratch.

  • Often act as entry points to the API.
  • May accept minimal input (or none) to generate data.
  • For each method that works with comparable types, there is a corresponding [name]Any variant that works with any types.
Method Description
Empty Returns an empty Enumerator[T] of type T that yields no values with comparable types only.
EmptyAny Returns an empty EnumeratorAny[T] of type T that yields no values with any types.
FromChannel Creates an Enumerator[T] that yields values received from a channel.
The enumeration continues until the channel is closed or the consumer stops iteration with comparable types only.
FromChannelAny Creates an EnumeratorAny[T] that yields values received from a channel.
The enumeration continues until the channel is closed or the consumer stops iteration with any types.
FromSlice Creates an Enumerator[T] that yields all elements from the input slice in order with comparable types only.
FromSliceAny Creates an EnumeratorAny[T] that yields all elements from the input slice in order with any types.
Range Generates a sequence of consecutive integers starting at 'start', producing exactly 'count' values in ascending order (with step +1) with comparable types only.
RangeAny Generates an EnumeratorAny[T] of consecutive integers starting at 'start', producing exactly 'count' values in ascending order (with step +1) with any types.
Repeat Generates a sequence containing the same item repeated 'count' times with comparable types only.
RepeatAny Generates an EnumeratorAny[T] containing the same item repeated 'count' times with any types.

⏳ Lazy Methods

Perform deferred computations, evaluating only when needed

  • Chainable without intermediate allocations.
  • Save memory/CPU until iteration.
Method Description
Concat Combines two enumerations into a single enumeration. The resulting enumeration yields all elements from the first enumeration, followed by all elements from the second enumeration.
Distinct Returns an enumerator that yields only unique elements from the original enumeration. Each element appears only once in the result, regardless of how many times it appears in the source.

⚠️ Performance note: This operation buffers all unique elements encountered so far in memory. For enumerations with many unique elements, memory usage can become significant. The operation is not memory-bounded
ℹ️ Available only for comparable types.
Except Returns an enumerator that yields elements from the first enumeration that are not present in the second enumeration. This is equivalent to set difference operation (first - second).

⚠️ Performance note: This operation completely buffers the second enumerator into memory (creates a map for fast lookup). For large second enumerations, this may consume significant memory. The memory usage is proportional to the number of unique elements in the second enumerator.
ℹ️ Available only for comparable types.
Intersect Returns an enumerator that yields elements present in both enumerations. This is equivalent to set intersection operation (first ∩ second).

⚠️ Performance note: The second enumeration is completely loaded into memory to enable fast lookups. Be cautious when using this with very large second enumerations as it may cause high memory usage.
ℹ️ Available only for comparable types.
Skip Bypasses a specified number of elements in an enumeration and then yields the remaining elements. This operation is useful for pagination, skipping headers, or bypassing initial elements.
SkipLast Bypasses a specified number of elements at the end of an enumeration and yields the remaining elements. This operation is useful for removing trailing elements like footers, summaries, or fixed-size endings from sequences.

⚠️ Performance note: This operation buffers up to n elements in memory using a circular buffer for efficient memory usage. For large values of n, this may consume significant memory.
⚠️ Evaluation note: This operation is partially lazy - elements are processed as the enumeration proceeds, but the last n elements are buffered and never yielded. The enumeration must progress beyond n elements to yield earlier ones.
SkipWhile Bypasses elements in an enumeration as long as a specified condition is true and then yields the remaining elements. This operation is useful for skipping elements until a certain condition is met.
Take Returns a specified number of contiguous elements from the start of an enumeration. This operation is useful for pagination, limiting results, or taking samples from sequences.
TakeLast Returns a specified number of contiguous elements from the end of an enumeration. This operation is useful for getting the final elements, such as last N records, trailing averages, or end-of-sequence markers.

⚠️ Performance note: This operation buffers up to n elements in memory to track which elements should be yielded. For large values of n, this may consume significant memory. All elements must be processed before any are yielded.
⚠️ Evaluation note: This operation is not lazy in the traditional sense - the entire source enumeration must be consumed before yielding begins. Elements are yielded in order of their appearance in the original enumeration.
TakeWhile Returns elements from an enumeration as long as a specified condition is true. This operation is useful for taking elements until a certain condition is met, such as taking elements while they are valid or within a range.
Union Produces the set union of two enumerations by using the default equality comparer. This operation returns unique elements that appear in either enumeration.

⚠️ Performance note: This operation buffers all unique elements encountered so far in memory. For enumerations with many unique elements, memory usage can become significant. The operation is not memory-bounded.
ℹ️ Available only for comparable types.
Where Filters an enumeration based on a predicate function. This operation returns elements that satisfy the specified condition.

🪄 Materialize Methods

Convert lazy sequences into concrete data structures.

  • Trigger all pending computations.
  • Require memory to store results.
Method Description
All Determines whether all elements in the enumeration satisfy a predicate. Returns true if every element matches the predicate, or if the enumeration is empty.
Any Determines whether an enumeration contains any elements. This operation is useful for checking if a sequence is non-empty.
Count Returns the number of elements in an enumeration. This operation is useful for determining the size of a sequence.

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to count all elements. For large enumerations, this may be expensive.
⚠️ Memory note: This operation does not buffer elements, but it must process the entire enumeration, which may trigger upstream operations.
FirstOrDefault Returns the first element of an enumeration, or a default value if the enumeration is empty or nil.
FirstOrNil Returns a pointer to the first element of an enumeration. This operation is useful for getting the first element when it exists, with the ability to distinguish between "no elements" and "zero value" cases.
ForEach Executes the specified action for each element in the enumeration. This operation is useful for performing side effects like printing, logging, or modifying external state for each element.

⚠️ Performance note: This operation must iterate through the entire enumeration, which may be expensive for large enumerations.
⚠️ Side effects warning: The action function may have side effects. Use with caution in functional programming contexts.
LastOrDefault Returns the last element of an enumeration, or a default value if the enumeration is empty or nil.

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to find the last element. For large enumerations, this may be expensive.
⚠️ Memory note: This operation does not buffer elements, but it must process the entire enumeration, which may trigger upstream operations.
LastOrNil Returns a pointer to the last element of an enumeration, or nil if the enumeration is empty or nil.

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to find the last element. For large enumerations, this may be expensive.
⚠️ Memory note: This operation does not buffer elements, but it must process the entire enumeration, which may trigger upstream operations.
LongCount Returns the number of elements in an enumeration as an int64. This operation is useful for determining the size of large sequences where the count might exceed the range of int.

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to count all elements. For large enumerations, this may be expensive.
⚠️ Memory note: This operation does not buffer elements, but it must process the entire enumeration, which may trigger upstream operations.
SumFloat Computes the sum of float32 values obtained by applying a selector function to each element in the enumeration. This operation is useful for calculating totals, aggregates, or numeric summaries with floating-point precision.

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to sum all values. For large enumerations, this may be expensive.
⚠️ Precision warning: Floating-point arithmetic may introduce small rounding errors. Consider using appropriate rounding for display.
SumInt Computes the sum of integers obtained by applying a selector function to each element in the enumeration. This operation is useful for calculating totals, aggregates, or numeric summaries.

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to sum all values. For large enumerations, this may be expensive.
⚠️ Overflow warning: Integer overflow may occur with very large sums. Consider using SumInt64 for larger ranges.
ToChannel Converts an enumeration to a channel that yields all elements. This operation is useful for converting lazy enumerations into channel-based processing pipelines or for interoperability with goroutines.

⚠️ Resource management: This operation starts a goroutine that runs until the enumeration is complete. Always consume all elements or the goroutine may block indefinitely.
⚠️ Blocking behavior: The goroutine will block when trying to send to a full channel if there's no reader. Use appropriate buffer size.
⚠️ Warning: If the returned channel is not fully consumed, the goroutine may leak. Always range over the entire channel or ensure proper cleanup.
ToMap Converts an enumeration to a map[T]struct{} for efficient set-like operations. This operation is useful for creating memory-efficient lookup collections or for removing duplicates while materializing an enumeration.

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration. For large enumerations, this may be expensive.
⚠️ Memory note: This operation buffers all unique elements in memory. The memory usage depends on the number of unique elements.
ℹ️ Available only for comparable types.
ToSlice Converts an enumeration to a slice containing all elements. This operation is useful for materializing lazy enumerations into concrete collections.

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to collect all elements. For large enumerations, this may be expensive in both time and memory.
⚠️ Memory note: This operation buffers all elements in memory.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Enumerator

type Enumerator[T comparable] func(yield func(T) bool)

Enumerator represents a sequence of values that can be iterated over using Go's range loop syntax (Go 1.22+ range-over-func feature). The iteration can be stopped early by the consumer returning false from the yield function.

Type Parameters:

T - the type of values to enumerate (must be comparable)

Notes: - Thread safety depends on the implementation - Designed to work with Go 1.22+ range-over-func feature

func Empty

func Empty[T comparable]() Enumerator[T]

Empty returns an empty enumerator of type T that yields no values.

The returned Enumerator[T] will immediately terminate any range loop without executing the loop body, as there are no values to enumerate.

Returns:

An empty Enumerator[T] that can be used in range loops (Go 1.22+).

Notes: - Can represent "no results" in a type-safe way - Works with any comparable type T

func FromChannel

func FromChannel[T comparable](ch <-chan T) Enumerator[T]

FromChannel creates an Enumerator[T] that yields values received from a channel. The enumeration continues until the channel is closed or the consumer stops iteration.

The enumerator will: - Yield each value received from the channel in order - Terminate when the channel is closed - Support early termination when the consumer returns false

Parameters:

ch - the source channel to enumerate (read-only)

Returns:

An Enumerator[T] that iterates over channel values

Notes: - The enumerator will block waiting for new values when channel is empty - If the channel is never closed, iteration may hang indefinitely - Safe for nil channels (will act like closed channels, producing no values) - Channel receive operations occur during enumeration (not beforehand) - The channel should only be read through the enumerator

func FromSlice

func FromSlice[T comparable](items []T) Enumerator[T]

FromSlice creates an Enumerator[T] that yields all elements from the input slice in order.

The enumerator will produce exactly len(items) values, one for each element in the original slice, preserving their original order. The iteration can be stopped early by the consumer.

Parameters:

items - slice of elements to enumerate (elements must be comparable)

Returns:

An Enumerator[T] that iterates over the slice elements

Notes: - The slice is captured by reference (modifications will affect iteration) - For empty slices, produces no values (like Empty()) - Safe for nil slices (treated as empty) - Preserves the original element order

func Range

func Range(start, count int) Enumerator[int]

Range generates a sequence of consecutive integers starting at 'start', producing exactly 'count' values in ascending order (with step +1).

Parameters:

start - initial value of the sequence (inclusive)
count - number of values to generate (must be non-negative)

Returns:

An Enumerator[int] that can be used in range loops.

Notes: - For count = 0, produces an empty sequence (no iterations) - For count < 0, behavior is undefined (should be avoided)

func Repeat

func Repeat[T comparable](item T, count int) Enumerator[T]

Repeat generates a sequence containing the same item repeated 'count' times.

Parameters:

item  - value to repeat (any comparable type)
count - number of repetitions (must be non-negative)

Returns:

An Enumerator[T] that can be used in range loops.

Notes: - For count = 0, produces an empty sequence (no iterations) - For count < 0, behavior is undefined (should be avoided) - Works with any comparable type T (int, string, structs etc.)

func (Enumerator[T]) All

func (q Enumerator[T]) All(predicate func(T) bool) bool

All determines whether all elements in the enumeration satisfy a predicate. Returns true if every element matches the predicate, or if the enumeration is empty.

The method will: - Apply the predicate to each element in the enumeration - Return false immediately when the first non-matching element is found - Return true if all elements match or if there are no elements - Short-circuit evaluation (stops at first false result)

Parameters:

predicate - a function that takes an element and returns true/false

Returns:

true if all elements satisfy the predicate or enumeration is empty
false if at least one element does not satisfy the predicate

Notes: - For empty enumerations, returns true (vacuous truth) - For nil enumerators, returns true (consistent with empty behavior) - Uses short-circuit evaluation for performance - The predicate function should be pure (no side effects) - Stops enumeration as soon as a non-matching element is found

func (Enumerator[T]) Any

func (q Enumerator[T]) Any() bool

Any determines whether an enumeration contains any elements. This operation is useful for checking if a sequence is non-empty.

The any operation will: - Return true if the enumeration contains at least one element - Return false if the enumeration is empty or nil - Stop enumeration immediately after finding the first element - Handle nil enumerators gracefully

Returns:

true if the enumeration contains any elements, false otherwise

Notes: - If the enumerator is nil, returns false - If the enumeration is empty, returns false - Lazy evaluation stops immediately after finding the first element - This is a terminal operation that materializes the enumeration - Very efficient - O(1) time complexity for non-empty enumerations - No elements are buffered - memory efficient

func (Enumerator[T]) Concat

func (q Enumerator[T]) Concat(second Enumerator[T]) Enumerator[T]

Concat combines two enumerations into a single enumeration. The resulting enumeration yields all elements from the first enumeration, followed by all elements from the second enumeration.

The concatenation will: - Yield all elements from the first enumeration in order - Then yield all elements from the second enumeration in order - Handle nil enumerators gracefully (treated as empty) - Support early termination when consumer returns false

Parameters:

second - the enumerator to concatenate after the current one

Returns:

A new Enumerator[T] that yields elements from both enumerations in sequence

Notes: - Nil enumerators are treated as empty (no elements yielded) - Both enumerations are consumed in order during iteration - If the first enumeration is infinite, second will never be reached - Lazy evaluation - elements are produced on-demand during iteration - No elements are buffered - memory efficient - Safe for use with any combination of nil and non-nil enumerators

func (Enumerator[T]) Count

func (q Enumerator[T]) Count() int

Count returns the number of elements in an enumeration. This operation is useful for determining the size of a sequence.

The count operation will: - Iterate through all elements in the enumeration - Count each element encountered - Return the total count - Handle nil enumerators gracefully

Returns:

The number of elements in the enumeration (0 for empty or nil enumerations)

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to count all elements. For large enumerations, this may be expensive.

⚠️ Memory note: This operation does not buffer elements, but it must process the entire enumeration, which may trigger upstream operations.

Notes: - If the enumerator is nil, returns 0 - If the enumeration is empty, returns 0 - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - All elements are processed, even if consumer wants to stop early

func (Enumerator[T]) Distinct

func (q Enumerator[T]) Distinct() Enumerator[T]

Distinct returns an enumerator that yields only unique elements from the original enumeration. Each element appears only once in the result, regardless of how many times it appears in the source.

The distinct operation will: - Yield each unique element exactly once - Preserve the order of first occurrence of each element - Use equality comparison (==) to determine uniqueness - Support early termination when consumer returns false

Returns:

An Enumerator[T] that yields unique elements in order of first appearance

⚠️ Performance note: This operation buffers all unique elements encountered so far in memory. For enumerations with many unique elements, memory usage can become significant. The operation is not memory-bounded.

Notes: - Requires T to be comparable (supports == operator) - Uses map[T]bool internally for tracking seen elements - Memory usage grows with number of unique elements - For nil enumerators, returns empty enumerator - Lazy evaluation - elements processed during iteration - Elements are compared using Go's built-in equality

func (Enumerator[T]) Except

func (q Enumerator[T]) Except(second Enumerator[T]) Enumerator[T]

Except returns an enumerator that yields elements from the first enumeration that are not present in the second enumeration. This is equivalent to set difference operation (first - second).

The except operation will: - Yield elements that exist in the first enumeration but not in the second - Remove duplicates from the result (each element appears only once) - Preserve the order of first occurrence from the first enumeration - Handle nil enumerators gracefully

Parameters:

second - the enumerator containing elements to exclude

Returns:

An Enumerator[T] that yields elements from first enumeration not in second

⚠️ Performance note: This operation completely buffers the `second` enumerator into memory (creates a map for fast lookup). For large second enumerations, this may consume significant memory. The memory usage is proportional to the number of unique elements in the second enumerator.

Notes: - Requires T to be comparable (supports == operator) - Uses map[T]bool internally for efficient lookup - Result contains only unique elements (duplicates removed) - For nil first enumerator, returns empty enumeration - For nil second enumerator, returns distinct elements from first - Lazy evaluation - elements processed during iteration - Memory usage depends on size of second enumeration and unique elements in first

func (Enumerator[T]) FirstOrDefault

func (q Enumerator[T]) FirstOrDefault(defaultValue T) T

FirstOrDefault returns the first element of an enumeration, or a default value if the enumeration is empty or nil.

The first or default operation will: - Return the first element from the enumeration if it exists - Return the provided default value if the enumeration is empty or nil - Stop enumeration immediately after finding the first element - Handle nil enumerators gracefully

Parameters:

defaultValue - the value to return if the enumeration is empty or nil

Returns:

The first element of the enumeration, or the default value if enumeration is empty

Notes: - If the enumerator is nil, returns the defaultValue - If the enumeration is empty, returns the defaultValue - Lazy evaluation stops immediately after finding the first element - This is a terminal operation that materializes the enumeration - Very efficient - O(1) time complexity for non-empty enumerations - No elements are buffered - memory efficient - Unlike FirstOrNil(), this method returns the value directly, not a pointer - Safe for all types including those with zero values like 0, "", false, etc. - When using zero value as default, consider using FirstOrNil() for distinction

func (Enumerator[T]) FirstOrNil

func (q Enumerator[T]) FirstOrNil() *T

FirstOrNil returns a pointer to the first element of an enumeration. This operation is useful for getting the first element when it exists, with the ability to distinguish between "no elements" and "zero value" cases.

The first operation will: - Return a pointer to the first element if the enumeration contains elements - Return nil if the enumeration is empty or nil - Stop enumeration immediately after finding the first element - Handle nil enumerators gracefully

Returns:

A pointer to the first element, or nil if enumeration is empty or nil

Notes: - If the enumerator is nil, returns nil - If the enumeration is empty, returns nil - Lazy evaluation stops immediately after finding the first element - This is a terminal operation that materializes the enumeration - Very efficient - O(1) time complexity for non-empty enumerations - No elements are buffered - memory efficient - Returns pointer to allow distinction between "no elements" (nil) and "zero value" element - Safe for all types including those with zero values like 0, "", false, etc.

func (Enumerator[T]) ForEach

func (q Enumerator[T]) ForEach(action func(T))

ForEach executes the specified action for each element in the enumeration. This operation is useful for performing side effects like printing, logging, or modifying external state for each element.

The for each operation will: - Execute the action function for each element in the enumeration - Process all elements in the enumeration - Handle nil enumerators gracefully - Not return any value (void operation)

Parameters:

action - the action to execute for each element

⚠️ Performance note: This operation must iterate through the entire enumeration, which may be expensive for large enumerations.

⚠️ Side effects warning: The action function may have side effects. Use with caution in functional programming contexts.

Notes: - If the enumerator is nil, no action is executed - This is a terminal operation that materializes the enumeration - All elements are processed regardless of action behavior - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - The enumeration stops only when exhausted or if upstream operations stop it - Action function should handle all possible values including zero values

func (Enumerator[T]) Intersect

func (q Enumerator[T]) Intersect(second Enumerator[T]) Enumerator[T]

Intersect returns an enumerator that yields elements present in both enumerations. This is equivalent to set intersection operation (first ∩ second).

The intersect operation will: - Yield elements that exist in both the first and second enumerations - Remove duplicates from the result (each element appears only once) - Preserve the order of first occurrence from the first enumeration - Handle nil enumerators gracefully

Parameters:

second - the enumerator to intersect with

Returns:

An Enumerator[T] that yields elements present in both enumerations

⚠️ Performance note: The second enumeration is completely loaded into memory to enable fast lookups. Be cautious when using this with very large second enumerations as it may cause high memory usage.

Notes: - Requires T to be comparable (supports == operator) - Uses map[T]bool internally for efficient lookup - Result contains only unique elements (duplicates removed) - For nil first enumerator, returns empty enumeration - For nil second enumerator, returns empty enumeration - Lazy evaluation - elements processed during iteration - Memory usage depends on size of second enumeration and unique elements in first - Elements are yielded in order of their first appearance in the first enumeration

func (Enumerator[T]) LastOrDefault

func (q Enumerator[T]) LastOrDefault(defaultValue T) T

LastOrDefault returns the last element of an enumeration, or a default value if the enumeration is empty or nil.

The last or default operation will: - Iterate through all elements in the enumeration - Keep track of the most recent element encountered - Return the last element if enumeration contains elements - Return the provided default value if the enumeration is empty or nil - Handle nil enumerators gracefully

Parameters:

defaultValue - the value to return if the enumeration is empty or nil

Returns:

The last element of the enumeration, or the default value if enumeration is empty

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to find the last element. For large enumerations, this may be expensive.

⚠️ Memory note: This operation does not buffer elements, but it must process the entire enumeration, which may trigger upstream operations.

Notes: - If the enumerator is nil, returns the defaultValue - If the enumeration is empty, returns the defaultValue - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - Unlike LastOrNil(), this method returns the value directly, not a pointer - Safe for all types including those with zero values like 0, "", false, etc. - When using zero value as default, consider using LastOrNil() for distinction

func (Enumerator[T]) LastOrNil

func (q Enumerator[T]) LastOrNil() *T

LastOrNil returns a pointer to the last element of an enumeration, or nil if the enumeration is empty or nil.

The last or nil operation will: - Iterate through all elements in the enumeration - Keep track of the most recent element encountered - Return a pointer to the last element if enumeration contains elements - Return nil if the enumeration is empty or nil - Handle nil enumerators gracefully

Returns:

A pointer to the last element, or nil if enumeration is empty or nil

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to find the last element. For large enumerations, this may be expensive.

⚠️ Memory note: This operation does not buffer elements, but it must process the entire enumeration, which may trigger upstream operations.

Notes: - If the enumerator is nil, returns nil - If the enumeration is empty, returns nil - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - Returns pointer to allow distinction between "no elements" (nil) and "zero value" element - Safe for all types including those with zero values like 0, "", false, etc.

func (Enumerator[T]) LongCount

func (q Enumerator[T]) LongCount() int64

LongCount returns the number of elements in an enumeration as an int64. This operation is useful for determining the size of large sequences where the count might exceed the range of int.

The long count operation will: - Iterate through all elements in the enumeration - Count each element encountered using int64 to prevent overflow - Return the total count as int64 - Handle nil enumerators gracefully

Returns:

The number of elements in the enumeration as int64 (0 for empty or nil enumerations)

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to count all elements. For large enumerations, this may be expensive.

⚠️ Memory note: This operation does not buffer elements, but it must process the entire enumeration, which may trigger upstream operations.

Notes: - If the enumerator is nil, returns 0 - If the enumeration is empty, returns 0 - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - In Go, int is platform-dependent (32-bit on 32-bit systems, 64-bit on 64-bit systems) - Use LongCount when you expect very large collections that might overflow int

func (Enumerator[T]) Skip

func (q Enumerator[T]) Skip(n int) Enumerator[T]

Skip bypasses a specified number of elements in an enumeration and then yields the remaining elements. This operation is useful for pagination, skipping headers, or bypassing initial elements.

The skip operation will: - Bypass the first n elements from the enumeration - Yield all remaining elements in order - Handle edge cases gracefully (n <= 0, n >= count) - Support early termination when consumer returns false

Parameters:

n - the number of elements to skip (must be non-negative)

Returns:

An Enumerator[T] that yields elements after skipping the first n elements

Notes: - If n <= 0, returns the original enumerator unchanged - If n >= total number of elements, returns an empty enumerator - If the original enumerator is nil, returns an empty enumerator (not nil) - Lazy evaluation - elements are processed and skipped during iteration - No elements are buffered - memory efficient - Negative values of n are treated as 0 - The enumeration is consumed sequentially, so skipped elements are still processed

func (Enumerator[T]) SkipLast

func (q Enumerator[T]) SkipLast(n int) Enumerator[T]

SkipLast bypasses a specified number of elements at the end of an enumeration and yields the remaining elements. This operation is useful for removing trailing elements like footers, summaries, or fixed-size endings from sequences.

The skip last operation will: - Buffer elements to track which are the final n elements - Yield elements only after confirming they are not among the last n - Handle edge cases gracefully (n <= 0, n >= count) - Support early termination when consumer returns false

Parameters:

n - the number of elements to skip from the end (must be non-negative)

Returns:

An Enumerator[T] that yields elements except the last n elements

⚠️ Performance note: This operation buffers up to n elements in memory using a circular buffer for efficient memory usage. For large values of n, this may consume significant memory.

⚠️ Evaluation note: This operation is partially lazy - elements are processed as the enumeration proceeds, but the last n elements are buffered and never yielded. The enumeration must progress beyond n elements to yield earlier ones.

Notes: - If n <= 0, returns the original enumerator unchanged - If n >= total number of elements, returns an empty enumerator - If the original enumerator is nil, returns an empty enumerator - Elements are yielded in order of their appearance in the original enumeration - Negative values of n are treated as 0

func (Enumerator[T]) SkipWhile

func (q Enumerator[T]) SkipWhile(predicate func(T) bool) Enumerator[T]

SkipWhile bypasses elements in an enumeration as long as a specified condition is true and then yields the remaining elements. This operation is useful for skipping elements until a certain condition is met.

The skip while operation will: - Bypass elements from the beginning while the predicate returns true - Once the predicate returns false for an element, yield that element and all subsequent elements - Support early termination when consumer returns false

Parameters:

predicate - a function that determines whether to skip an element

Returns:

An Enumerator[T] that yields elements after skipping initial elements that match the condition

Notes: - If the predicate never returns false, returns an empty enumerator - If the predicate immediately returns false for the first element, returns the original enumerator - If the original enumerator is nil, returns an empty enumerator - Lazy evaluation - elements are processed and evaluated during iteration - No elements are buffered - memory efficient - The enumeration stops skipping as soon as the first non-matching element is found - Once skipping stops, all remaining elements are yielded (even if they would match the predicate)

func (Enumerator[T]) SumFloat

func (q Enumerator[T]) SumFloat(selector func(T) float32) float32

SumFloat computes the sum of float32 values obtained by applying a selector function to each element in the enumeration. This operation is useful for calculating totals, aggregates, or numeric summaries with floating-point precision.

The sum float operation will: - Apply the selector function to each element to extract a float32 value - Sum all the extracted float32 values - Return the total sum - Handle nil enumerators gracefully

Parameters:

selector - a function that extracts a float32 value from each element

Returns:

The sum of all float32 values extracted from the elements

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to sum all values. For large enumerations, this may be expensive.

⚠️ Precision warning: Floating-point arithmetic may introduce small rounding errors. Consider using appropriate rounding for display.

Notes: - If the enumerator is nil, returns 0 - If the enumeration is empty, returns 0 - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - The enumeration stops only when exhausted or if upstream operations stop it - Selector function should handle all possible input values safely - For double precision, consider implementing or using SumFloat64

func (Enumerator[T]) SumInt

func (q Enumerator[T]) SumInt(selector func(T) int) int

SumInt computes the sum of integers obtained by applying a selector function to each element in the enumeration. This operation is useful for calculating totals, aggregates, or numeric summaries.

The sum int operation will: - Apply the selector function to each element to extract an integer value - Sum all the extracted integer values - Return the total sum - Handle nil enumerators gracefully

Parameters:

selector - a function that extracts an integer value from each element

Returns:

The sum of all integer values extracted from the elements

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to sum all values. For large enumerations, this may be expensive.

⚠️ Overflow warning: Integer overflow may occur with very large sums. Consider using SumInt64 for larger ranges.

Notes: - If the enumerator is nil, returns 0 - If the enumeration is empty, returns 0 - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - The enumeration stops only when exhausted or if upstream operations stop it - Selector function should handle all possible input values safely

func (Enumerator[T]) Take

func (q Enumerator[T]) Take(n int) Enumerator[T]

Take returns a specified number of contiguous elements from the start of an enumeration. This operation is useful for pagination, limiting results, or taking samples from sequences.

The take operation will: - Yield the first n elements from the enumeration - Stop enumeration once n elements have been yielded - Handle edge cases gracefully (n <= 0, n >= count) - Support early termination when consumer returns false

Parameters:

n - the number of elements to take (must be non-negative)

Returns:

An Enumerator[T] that yields at most n elements from the start

Notes: - If n <= 0, returns an empty enumerator - If n >= total number of elements, returns all available elements - If the original enumerator is nil, returns an empty enumerator - Lazy evaluation - elements are processed and yielded during iteration - No elements are buffered - memory efficient - Negative values of n are treated as 0 - Early termination by the consumer stops further enumeration - The enumeration stops as soon as n elements are yielded or the source is exhausted

func (Enumerator[T]) TakeLast

func (q Enumerator[T]) TakeLast(n int) Enumerator[T]

TakeLast returns a specified number of contiguous elements from the end of an enumeration. This operation is useful for getting the final elements, such as last N records, trailing averages, or end-of-sequence markers.

The take last operation will: - Buffer elements to track the last n elements seen so far - Yield the final n elements when enumeration completes - Handle edge cases gracefully (n <= 0, n >= count) - Support early termination when consumer returns false

Parameters:

n - the number of elements to take from the end (must be non-negative)

Returns:

An Enumerator[T] that yields the last n elements

⚠️ Performance note: This operation buffers up to n elements in memory to track which elements should be yielded. For large values of n, this may consume significant memory. All elements must be processed before any are yielded.

⚠️ Evaluation note: This operation is not lazy in the traditional sense - the entire source enumeration must be consumed before yielding begins. Elements are yielded in order of their appearance in the original enumeration.

Notes: - If n <= 0, returns an empty enumerator - If n >= total number of elements, returns all available elements - If the original enumerator is nil, returns an empty enumerator - Negative values of n are treated as 0 - The enumeration stops as soon as the consumer returns false

func (Enumerator[T]) TakeWhile

func (q Enumerator[T]) TakeWhile(predicate func(T) bool) Enumerator[T]

TakeWhile returns elements from an enumeration as long as a specified condition is true. This operation is useful for taking elements until a certain condition is met, such as taking elements while they are valid or within a range.

The take while operation will: - Yield elements from the start while the predicate returns true - Stop enumeration as soon as the predicate returns false for an element - Handle edge cases gracefully (nil enumerator, always false predicate) - Support early termination when consumer returns false

Parameters:

predicate - a function that determines whether to take an element

Returns:

An Enumerator[T] that yields elements while the condition is true

Notes: - If the predicate immediately returns false for the first element, returns empty enumerator - If the predicate never returns false, returns all elements from the enumeration - If the original enumerator is nil, returns an empty enumerator - Lazy evaluation - elements are processed and evaluated during iteration - No elements are buffered - memory efficient - The enumeration stops as soon as the predicate returns false or consumer returns false - Once the predicate returns false for any element, no subsequent elements are evaluated

func (Enumerator[T]) ToChannel

func (q Enumerator[T]) ToChannel(bufferSize int) <-chan T

ToChannel converts an enumeration to a channel that yields all elements. This operation is useful for converting lazy enumerations into channel-based processing pipelines or for interoperability with goroutines.

The to channel operation will: - Create a new channel with specified buffer size - Start a goroutine that iterates through the enumeration - Send each element to the channel - Close the channel when enumeration is complete - Handle nil enumerators gracefully

Parameters:

bufferSize - the buffer size for the returned channel (0 for unbuffered)

Returns:

A read-only channel containing all elements from the enumeration

⚠️ Resource management: This operation starts a goroutine that runs until the enumeration is complete. Always consume all elements or the goroutine may block indefinitely.

⚠️ Blocking behavior: The goroutine will block when trying to send to a full channel if there's no reader. Use appropriate buffer size.

⚠️ Warning: If the returned channel is not fully consumed, the goroutine may leak. Always range over the entire channel or ensure proper cleanup.

Notes: - If the enumerator is nil, returns a closed channel - If the enumeration is empty, returns an empty but closed channel - The goroutine automatically closes the channel when done - Time complexity: O(n) where n is the number of elements - Space complexity: O(bufferSize) plus any upstream buffering - The enumeration runs in a separate goroutine, enabling concurrent processing

func (Enumerator[T]) ToMap

func (q Enumerator[T]) ToMap() map[T]struct{}

ToMap converts an enumeration to a map[T]struct{} for efficient set-like operations. This operation is useful for creating memory-efficient lookup collections or for removing duplicates while materializing an enumeration.

The to map operation will: - Iterate through all elements in the enumeration - Add each element as a key in the resulting map with empty struct value - Automatically remove duplicates (map key uniqueness) - Return the resulting map - Handle nil enumerators gracefully by returning an empty map

Returns:

A map[T]struct{} containing all unique elements as keys,
or an empty map if enumerator is nil or enumeration is empty

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration. For large enumerations, this may be expensive.

⚠️ Memory note: This operation buffers all unique elements in memory. The memory usage depends on the number of unique elements.

Notes: - If the enumerator is nil, returns an empty map (not nil) - If the enumeration is empty, returns an empty map - Automatically removes duplicates due to map key uniqueness - Uses map[T]struct{} for memory efficiency (struct{} takes zero memory) - Time complexity: O(n) where n is the number of elements - Space complexity: O(k) where k is the number of unique elements - Keys in the returned map are the unique elements from the enumeration - Values in the returned map are empty structs (zero memory footprint) - Check for element presence using: if _, exists := map[key]; exists { ... } - More memory-efficient than map[T]bool since struct{} takes no memory - Always returns a valid map, never nil - safe for immediate use

func (Enumerator[T]) ToSlice

func (q Enumerator[T]) ToSlice() []T

ToSlice converts an enumeration to a slice containing all elements. This operation is useful for materializing lazy enumerations into concrete collections.

The to slice operation will: - Iterate through all elements in the enumeration - Collect all elements into a new slice - Return the slice containing all elements in order - Handle nil enumerators gracefully

Returns:

A slice containing all elements from the enumeration, or empty slice if enumerator is nil

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to collect all elements. For large enumerations, this may be expensive in both time and memory.

⚠️ Memory note: This operation buffers all elements in memory.

Notes: - If the enumerator is nil, returns an empty slice (not nil) - If the enumeration is empty, returns an empty slice - For very large enumerations, consider processing elements incrementally. - Time complexity: O(n) where n is the number of elements - Space complexity: O(n) - allocates memory for all elements - The enumeration stops only when exhausted or if upstream operations stop it - Returned slice preserves the order of elements from the enumeration - Use with caution for infinite or very large enumerations

func (Enumerator[T]) Union

func (q Enumerator[T]) Union(second Enumerator[T]) Enumerator[T]

Union produces the set union of two enumerations by using the default equality comparer. This operation returns unique elements that appear in either enumeration.

The union operation will: - Yield all unique elements from the first enumeration - Then yield unique elements from the second enumeration that haven't been seen yet - Remove duplicates both within each enumeration and between enumerations - Preserve the order of first occurrence of each element - Handle nil enumerators gracefully - Support early termination when consumer returns false

Parameters:

second - the enumerator to union with the current one

Returns:

An Enumerator[T] that yields unique elements from both enumerations

⚠️ Performance note: This operation buffers all unique elements encountered so far in memory. For enumerations with many unique elements, memory usage can become significant. The operation is not memory-bounded.

Notes:

  • Requires T to be comparable (supports == operator)
  • Uses map[T]bool internally for tracking seen elements
  • Memory usage grows with number of unique elements from both enumerations
  • For nil enumerators, treats them as empty enumerations
  • Lazy evaluation - elements are processed during iteration
  • Elements are yielded in order: first unique elements from the first enumeration, then unique elements from the second enumeration that weren't in the first
  • Early termination by the consumer stops further enumeration of both sources

Union produces the set union of two enumerations by using the default equality comparer.

func (Enumerator[T]) Where

func (q Enumerator[T]) Where(predicate func(T) bool) Enumerator[T]

Where filters an enumeration based on a predicate function. This operation returns elements that satisfy the specified condition.

The where operation will: - Apply the predicate function to each element in the enumeration - Yield only elements for which the predicate returns true - Preserve the original order of elements that pass the filter - Handle nil enumerators gracefully - Support early termination when consumer returns false

Parameters:

predicate - a function that determines whether to include an element

Returns:

An Enumerator[T] that yields elements satisfying the predicate

Notes: - If the original enumerator is nil, returns an empty enumerator - Lazy evaluation - elements are processed and filtered during iteration - No elements are buffered - memory efficient - The enumeration stops when the source is exhausted or consumer returns false - Predicate function should be pure (no side effects) for predictable behavior - Elements for which predicate returns false are simply skipped

type EnumeratorAny

type EnumeratorAny[T any] func(yield func(T) bool)

EnumeratorAny represents a sequence of values that can be iterated over using Go's range loop syntax (Go 1.22+ range-over-func feature). The iteration can be stopped early by the consumer returning false from

the yield function.

Type Parameters:

T - the type of values to enumerate (no constraints)

Notes: - Thread safety depends on the implementation - Designed to work with Go 1.22+ range-over-func feature

func EmptyAny

func EmptyAny[T any]() EnumeratorAny[T]

EmptyAny returns an empty enumerator of type T that yields no values.

The returned EnumeratorAny[T] will immediately terminate any range loop without executing the loop body, as there are no values to enumerate.

Returns:

An empty EnumeratorAny[T] that can be used in range loops (Go 1.22+).

Notes: - Can represent "no results" in a type-safe way - Works with any type T (no constraints)

func FromChannelAny

func FromChannelAny[T any](ch <-chan T) EnumeratorAny[T]

FromChannelAny creates an EnumeratorAny[T] that yields values received from a channel. The enumeration continues until the channel is closed or the consumer stops iteration.

The enumerator will: - Yield each value received from the channel in order - Terminate when the channel is closed - Support early termination when the consumer returns false

Parameters:

ch - the source channel to enumerate (read-only)

Returns:

An EnumeratorAny[T] that iterates over channel values

Notes: - The enumerator will block waiting for new values when channel is empty - If the channel is never closed, iteration may hang indefinitely - Safe for nil channels (will act like closed channels, producing no values) - Channel receive operations occur during enumeration (not beforehand) - The channel should only be read through the enumerator

func FromSliceAny

func FromSliceAny[T any](items []T) EnumeratorAny[T]

FromSliceAny creates an EnumeratorAny[T] that yields all elements from the input slice in order.

The enumerator will produce exactly len(items) values, one for each element in the original slice, preserving their original order. The iteration can be stopped early by the consumer.

Parameters:

items - slice of elements to enumerate (no type constraints)

Returns:

An EnumeratorAny[T] that iterates over the slice elements

Notes: - The slice is captured by reference (modifications will affect iteration) - For empty slices, produces no values - Safe for nil slices (treated as empty) - Preserves the original element order

func RangeAny

func RangeAny(start, count int) EnumeratorAny[int]

RangeAny generates a sequence of consecutive integers starting at 'start', producing exactly 'count' values in ascending order (with step +1).

Parameters:

start - initial value of the sequence (inclusive)
count - number of values to generate (must be non-negative)

Returns:

An EnumeratorAny[int] that can be used in range loops.

Notes: - For count = 0, produces an empty sequence (no iterations) - For count < 0, behavior is undefined (should be avoided)

func RepeatAny

func RepeatAny[T any](item T, count int) EnumeratorAny[T]

RepeatAny generates a sequence containing the same item repeated 'count' times.

Parameters:

item  - value to repeat (any type)
count - number of repetitions (must be non-negative)

Returns:

An EnumeratorAny[T] that can be used in range loops.

Notes: - For count = 0, produces an empty sequence (no iterations) - For count < 0, behavior is undefined (should be avoided) - Works with any type T (comparable and non-comparable types)

func (EnumeratorAny[T]) All

func (q EnumeratorAny[T]) All(predicate func(T) bool) bool

All determines whether all elements in the enumeration satisfy a predicate. Returns true if every element matches the predicate, or if the enumeration is empty.

The method will: - Apply the predicate to each element in the enumeration - Return false immediately when the first non-matching element is found - Return true if all elements match or if there are no elements - Short-circuit evaluation (stops at first false result)

Parameters:

predicate - a function that takes an element and returns true/false

Returns:

true if all elements satisfy the predicate or enumeration is empty
false if at least one element does not satisfy the predicate

Notes: - For empty enumerations, returns true (vacuous truth) - For nil enumerators, returns true (consistent with empty behavior) - Uses short-circuit evaluation for performance - The predicate function should be pure (no side effects) - Stops enumeration as soon as a non-matching element is found

func (EnumeratorAny[T]) Any

func (q EnumeratorAny[T]) Any() bool

Any determines whether an enumeration contains any elements. This operation is useful for checking if a sequence is non-empty.

The any operation will: - Return true if the enumeration contains at least one element - Return false if the enumeration is empty or nil - Stop enumeration immediately after finding the first element - Handle nil enumerators gracefully

Returns:

true if the enumeration contains any elements, false otherwise

Notes: - If the enumerator is nil, returns false - If the enumeration is empty, returns false - Lazy evaluation stops immediately after finding the first element - This is a terminal operation that materializes the enumeration - Very efficient - O(1) time complexity for non-empty enumerations - No elements are buffered - memory efficient

func (EnumeratorAny[T]) Concat

func (q EnumeratorAny[T]) Concat(second EnumeratorAny[T]) EnumeratorAny[T]

Concat combines two enumerations into a single enumeration. The resulting enumeration yields all elements from the first enumeration, followed by all elements from the second enumeration.

The concatenation will: - Yield all elements from the first enumeration in order - Then yield all elements from the second enumeration in order - Handle nil enumerators gracefully (treated as empty) - Support early termination when consumer returns false

Parameters:

second - the enumerator to concatenate after the current one

Returns:

A new EnumeratorAny[T] that yields elements from both enumerations in sequence

Notes: - Nil enumerators are treated as empty (no elements yielded) - Both enumerations are consumed in order during iteration - If the first enumeration is infinite, second will never be reached - Lazy evaluation - elements are produced on-demand during iteration - No elements are buffered - memory efficient - Safe for use with any combination of nil and non-nil enumerators

func (EnumeratorAny[T]) Count

func (q EnumeratorAny[T]) Count() int

Count returns the number of elements in an enumeration. This operation is useful for determining the size of a sequence.

The count operation will: - Iterate through all elements in the enumeration - Count each element encountered - Return the total count - Handle nil enumerators gracefully

Returns:

The number of elements in the enumeration (0 for empty or nil enumerations)

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to count all elements. For large enumerations, this may be expensive.

⚠️ Memory note: This operation does not buffer elements, but it must process the entire enumeration, which may trigger upstream operations.

Notes: - If the enumerator is nil, returns 0 - If the enumeration is empty, returns 0 - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - All elements are processed, even if consumer wants to stop early

func (EnumeratorAny[T]) FirstOrDefault

func (q EnumeratorAny[T]) FirstOrDefault(defaultValue T) T

FirstOrDefault returns the first element of an enumeration, or a default value if the enumeration is empty or nil.

The first or default operation will: - Return the first element from the enumeration if it exists - Return the provided default value if the enumeration is empty or nil - Stop enumeration immediately after finding the first element - Handle nil enumerators gracefully

Parameters:

defaultValue - the value to return if the enumeration is empty or nil

Returns:

The first element of the enumeration, or the default value if enumeration is empty

Notes: - If the enumerator is nil, returns the defaultValue - If the enumeration is empty, returns the defaultValue - Lazy evaluation stops immediately after finding the first element - This is a terminal operation that materializes the enumeration - Very efficient - O(1) time complexity for non-empty enumerations - No elements are buffered - memory efficient - Unlike FirstOrNil(), this method returns the value directly, not a pointer - Safe for all types including those with zero values like 0, "", false, etc. - When using zero value as default, consider using FirstOrNil() for distinction

func (EnumeratorAny[T]) FirstOrNil

func (q EnumeratorAny[T]) FirstOrNil() *T

FirstOrNil returns a pointer to the first element of an enumeration. This operation is useful for getting the first element when it exists, with the ability to distinguish between "no elements" and "zero value" cases.

The first operation will: - Return a pointer to the first element if the enumeration contains elements - Return nil if the enumeration is empty or nil - Stop enumeration immediately after finding the first element - Handle nil enumerators gracefully

Returns:

A pointer to the first element, or nil if enumeration is empty or nil

Notes: - If the enumerator is nil, returns nil - If the enumeration is empty, returns nil - Lazy evaluation stops immediately after finding the first element - This is a terminal operation that materializes the enumeration - Very efficient - O(1) time complexity for non-empty enumerations - No elements are buffered - memory efficient - Returns pointer to allow distinction between "no elements" (nil) and "zero value" element - Safe for all types including those with zero values like 0, "", false, etc.

func (EnumeratorAny[T]) ForEach

func (q EnumeratorAny[T]) ForEach(action func(T))

ForEach executes the specified action for each element in the enumeration. This operation is useful for performing side effects like printing, logging, or modifying external state for each element.

The for each operation will: - Execute the action function for each element in the enumeration - Process all elements in the enumeration - Handle nil enumerators gracefully - Not return any value (void operation)

Parameters:

action - the action to execute for each element

⚠️ Performance note: This operation must iterate through the entire enumeration, which may be expensive for large enumerations.

⚠️ Side effects warning: The action function may have side effects. Use with caution in functional programming contexts.

Notes: - If the enumerator is nil, no action is executed - This is a terminal operation that materializes the enumeration - All elements are processed regardless of action behavior - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - The enumeration stops only when exhausted or if upstream operations stop it - Action function should handle all possible values including zero values

func (EnumeratorAny[T]) LastOrDefault

func (q EnumeratorAny[T]) LastOrDefault(defaultValue T) T

LastOrDefault returns the last element of an enumeration, or a default value if the enumeration is empty or nil.

The last or default operation will: - Iterate through all elements in the enumeration - Keep track of the most recent element encountered - Return the last element if enumeration contains elements - Return the provided default value if the enumeration is empty or nil - Handle nil enumerators gracefully

Parameters:

defaultValue - the value to return if the enumeration is empty or nil

Returns:

The last element of the enumeration, or the default value if enumeration is empty

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to find the last element. For large enumerations, this may be expensive.

⚠️ Memory note: This operation does not buffer elements, but it must process the entire enumeration, which may trigger upstream operations.

Notes: - If the enumerator is nil, returns the defaultValue - If the enumeration is empty, returns the defaultValue - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - Unlike LastOrNil(), this method returns the value directly, not a pointer - Safe for all types including those with zero values like 0, "", false, etc. - When using zero value as default, consider using LastOrNil() for distinction

func (EnumeratorAny[T]) LastOrNil

func (q EnumeratorAny[T]) LastOrNil() *T

LastOrNil returns a pointer to the last element of an enumeration, or nil if the enumeration is empty or nil.

The last or nil operation will: - Iterate through all elements in the enumeration - Keep track of the most recent element encountered - Return a pointer to the last element if enumeration contains elements - Return nil if the enumeration is empty or nil - Handle nil enumerators gracefully

Returns:

A pointer to the last element, or nil if enumeration is empty or nil

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to find the last element. For large enumerations, this may be expensive.

⚠️ Memory note: This operation does not buffer elements, but it must process the entire enumeration, which may trigger upstream operations.

Notes: - If the enumerator is nil, returns nil - If the enumeration is empty, returns nil - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - Returns pointer to allow distinction between "no elements" (nil) and "zero value" element - Safe for all types including those with zero values like 0, "", false, etc.

func (EnumeratorAny[T]) LongCount

func (q EnumeratorAny[T]) LongCount() int64

LongCount returns the number of elements in an enumeration as an int64. This operation is useful for determining the size of large sequences where the count might exceed the range of int.

The long count operation will: - Iterate through all elements in the enumeration - Count each element encountered using int64 to prevent overflow - Return the total count as int64 - Handle nil enumerators gracefully

Returns:

The number of elements in the enumeration as int64 (0 for empty or nil enumerations)

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to count all elements. For large enumerations, this may be expensive.

⚠️ Memory note: This operation does not buffer elements, but it must process the entire enumeration, which may trigger upstream operations.

Notes: - If the enumerator is nil, returns 0 - If the enumeration is empty, returns 0 - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - In Go, int is platform-dependent (32-bit on 32-bit systems, 64-bit on 64-bit systems) - Use LongCount when you expect very large collections that might overflow int

func (EnumeratorAny[T]) Skip

func (q EnumeratorAny[T]) Skip(n int) EnumeratorAny[T]

Skip bypasses a specified number of elements in an enumeration and then yields the remaining elements. This operation is useful for pagination, skipping headers, or bypassing initial elements.

The skip operation will: - Bypass the first n elements from the enumeration - Yield all remaining elements in order - Handle edge cases gracefully (n <= 0, n >= count) - Support early termination when consumer returns false

Parameters:

n - the number of elements to skip (must be non-negative)

Returns:

An EnumeratorAny[T] that yields elements after skipping the first n elements

Notes: - If n <= 0, returns the original enumerator unchanged - If n >= total number of elements, returns an empty enumerator - If the original enumerator is nil, returns an empty enumerator (not nil) - Lazy evaluation - elements are processed and skipped during iteration - No elements are buffered - memory efficient - Negative values of n are treated as 0 - The enumeration is consumed sequentially, so skipped elements are still processed

func (EnumeratorAny[T]) SkipLast

func (q EnumeratorAny[T]) SkipLast(n int) EnumeratorAny[T]

SkipLast bypasses a specified number of elements at the end of an enumeration and yields the remaining elements. This operation is useful for removing trailing elements like footers, summaries, or fixed-size endings from sequences.

The skip last operation will: - Buffer elements to track which are the final n elements - Yield elements only after confirming they are not among the last n - Handle edge cases gracefully (n <= 0, n >= count) - Support early termination when consumer returns false

Parameters:

n - the number of elements to skip from the end (must be non-negative)

Returns:

An EnumeratorAny[T] that yields elements except the last n elements

⚠️ Performance note: This operation buffers up to n elements in memory using a circular buffer for efficient memory usage. For large values of n, this may consume significant memory.

⚠️ Evaluation note: This operation is partially lazy - elements are processed as the enumeration proceeds, but the last n elements are buffered and never yielded. The enumeration must progress beyond n elements to yield earlier ones.

Notes: - If n <= 0, returns the original enumerator unchanged - If n >= total number of elements, returns an empty enumerator - If the original enumerator is nil, returns an empty enumerator - Elements are yielded in order of their appearance in the original enumeration - Negative values of n are treated as 0

func (EnumeratorAny[T]) SkipWhile

func (q EnumeratorAny[T]) SkipWhile(predicate func(T) bool) EnumeratorAny[T]

SkipWhile bypasses elements in an enumeration as long as a specified condition is true and then yields the remaining elements. This operation is useful for skipping elements until a certain condition is met.

The skip while operation will: - Bypass elements from the beginning while the predicate returns true - Once the predicate returns false for an element, yield that element and all subsequent elements - Support early termination when consumer returns false

Parameters:

predicate - a function that determines whether to skip an element

Returns:

An EnumeratorAny[T] that yields elements after skipping initial elements that match the condition

Notes: - If the predicate never returns false, returns an empty enumerator - If the predicate immediately returns false for the first element, returns the original enumerator - If the original enumerator is nil, returns an empty enumerator - Lazy evaluation - elements are processed and evaluated during iteration - No elements are buffered - memory efficient - The enumeration stops skipping as soon as the first non-matching element is found - Once skipping stops, all remaining elements are yielded (even if they would match the predicate)

func (EnumeratorAny[T]) SumFloat

func (q EnumeratorAny[T]) SumFloat(selector func(T) float32) float32

SumFloat computes the sum of float32 values obtained by applying a selector function to each element in the enumeration. This operation is useful for calculating totals, aggregates, or numeric summaries with floating-point precision.

The sum float operation will: - Apply the selector function to each element to extract a float32 value - Sum all the extracted float32 values - Return the total sum - Handle nil enumerators gracefully

Parameters:

selector - a function that extracts a float32 value from each element

Returns:

The sum of all float32 values extracted from the elements

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to sum all values. For large enumerations, this may be expensive.

⚠️ Precision warning: Floating-point arithmetic may introduce small rounding errors. Consider using appropriate rounding for display.

Notes: - If the enumerator is nil, returns 0 - If the enumeration is empty, returns 0 - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - The enumeration stops only when exhausted or if upstream operations stop it - Selector function should handle all possible input values safely - For double precision, consider implementing or using SumFloat64

func (EnumeratorAny[T]) SumInt

func (q EnumeratorAny[T]) SumInt(selector func(T) int) int

SumInt computes the sum of integers obtained by applying a selector function to each element in the enumeration. This operation is useful for calculating totals, aggregates, or numeric summaries.

The sum int operation will: - Apply the selector function to each element to extract an integer value - Sum all the extracted integer values - Return the total sum - Handle nil enumerators gracefully

Parameters:

selector - a function that extracts an integer value from each element

Returns:

The sum of all integer values extracted from the elements

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to sum all values. For large enumerations, this may be expensive.

⚠️ Overflow warning: Integer overflow may occur with very large sums. Consider using SumInt64 for larger ranges.

Notes: - If the enumerator is nil, returns 0 - If the enumeration is empty, returns 0 - Time complexity: O(n) where n is the number of elements - Space complexity: O(1) - constant space usage - The enumeration stops only when exhausted or if upstream operations stop it - Selector function should handle all possible input values safely

func (EnumeratorAny[T]) Take

func (q EnumeratorAny[T]) Take(n int) EnumeratorAny[T]

Take returns a specified number of contiguous elements from the start of an enumeration. This operation is useful for pagination, limiting results, or taking samples from sequences.

The take operation will: - Yield the first n elements from the enumeration - Stop enumeration once n elements have been yielded - Handle edge cases gracefully (n <= 0, n >= count) - Support early termination when consumer returns false

Parameters:

n - the number of elements to take (must be non-negative)

Returns:

An EnumeratorAny[T] that yields at most n elements from the start

Notes: - If n <= 0, returns an empty enumerator - If n >= total number of elements, returns all available elements - If the original enumerator is nil, returns an empty enumerator - Lazy evaluation - elements are processed and yielded during iteration - No elements are buffered - memory efficient - Negative values of n are treated as 0 - Early termination by the consumer stops further enumeration - The enumeration stops as soon as n elements are yielded or the source is exhausted

func (EnumeratorAny[T]) TakeLast

func (q EnumeratorAny[T]) TakeLast(n int) EnumeratorAny[T]

TakeLast returns a specified number of contiguous elements from the end of an enumeration. This operation is useful for getting the final elements, such as last N records, trailing averages, or end-of-sequence markers.

The take last operation will: - Buffer elements to track the last n elements seen so far - Yield the final n elements when enumeration completes - Handle edge cases gracefully (n <= 0, n >= count) - Support early termination when consumer returns false

Parameters:

n - the number of elements to take from the end (must be non-negative)

Returns:

An EnumeratorAny[T] that yields the last n elements

⚠️ Performance note: This operation buffers up to n elements in memory to track which elements should be yielded. For large values of n, this may consume significant memory. All elements must be processed before any are yielded.

⚠️ Evaluation note: This operation is not lazy in the traditional sense - the entire source enumeration must be consumed before yielding begins. Elements are yielded in order of their appearance in the original enumeration.

Notes: - If n <= 0, returns an empty enumerator - If n >= total number of elements, returns all available elements - If the original enumerator is nil, returns an empty enumerator - Negative values of n are treated as 0 - The enumeration stops as soon as the consumer returns false

func (EnumeratorAny[T]) TakeWhile

func (q EnumeratorAny[T]) TakeWhile(predicate func(T) bool) EnumeratorAny[T]

TakeWhile returns elements from an enumeration as long as a specified condition is true. This operation is useful for taking elements until a certain condition is met, such as taking elements while they are valid or within a range.

The take while operation will: - Yield elements from the start while the predicate returns true - Stop enumeration as soon as the predicate returns false for an element - Handle edge cases gracefully (nil enumerator, always false predicate) - Support early termination when consumer returns false

Parameters:

predicate - a function that determines whether to take an element

Returns:

An EnumeratorAny[T] that yields elements while the condition is true

Notes: - If the predicate immediately returns false for the first element, returns empty enumerator - If the predicate never returns false, returns all elements from the enumeration - If the original enumerator is nil, returns an empty enumerator - Lazy evaluation - elements are processed and evaluated during iteration - No elements are buffered - memory efficient - The enumeration stops as soon as the predicate returns false or consumer returns false - Once the predicate returns false for any element, no subsequent elements are evaluated

func (EnumeratorAny[T]) ToChannel

func (q EnumeratorAny[T]) ToChannel(bufferSize int) <-chan T

ToChannel converts an enumeration to a channel that yields all elements. This operation is useful for converting lazy enumerations into channel-based processing pipelines or for interoperability with goroutines.

The to channel operation will: - Create a new channel with specified buffer size - Start a goroutine that iterates through the enumeration - Send each element to the channel - Close the channel when enumeration is complete - Handle nil enumerators gracefully

Parameters:

bufferSize - the buffer size for the returned channel (0 for unbuffered)

Returns:

A read-only channel containing all elements from the enumeration

⚠️ Resource management: This operation starts a goroutine that runs until the enumeration is complete. Always consume all elements or the goroutine may block indefinitely.

⚠️ Blocking behavior: The goroutine will block when trying to send to a full channel if there's no reader. Use appropriate buffer size.

⚠️ Warning: If the returned channel is not fully consumed, the goroutine may leak. Always range over the entire channel or ensure proper cleanup.

Notes: - If the enumerator is nil, returns a closed channel - If the enumeration is empty, returns an empty but closed channel - The goroutine automatically closes the channel when done - Time complexity: O(n) where n is the number of elements - Space complexity: O(bufferSize) plus any upstream buffering - The enumeration runs in a separate goroutine, enabling concurrent processing

func (EnumeratorAny[T]) ToSlice

func (q EnumeratorAny[T]) ToSlice() []T

ToSlice converts an enumeration to a slice containing all elements. This operation is useful for materializing lazy enumerations into concrete collections.

The to slice operation will: - Iterate through all elements in the enumeration - Collect all elements into a new slice - Return the slice containing all elements in order - Handle nil enumerators gracefully

Returns:

A slice containing all elements from the enumeration, or empty slice if enumerator is nil

⚠️ Performance note: This is a terminal operation that must iterate through the entire enumeration to collect all elements. For large enumerations, this may be expensive in both time and memory.

⚠️ Memory note: This operation buffers all elements in memory.

Notes: - If the enumerator is nil, returns an empty slice (not nil) - If the enumeration is empty, returns an empty slice - For very large enumerations, consider processing elements incrementally. - Time complexity: O(n) where n is the number of elements - Space complexity: O(n) - allocates memory for all elements - The enumeration stops only when exhausted or if upstream operations stop it - Returned slice preserves the order of elements from the enumeration - Use with caution for infinite or very large enumerations

func (EnumeratorAny[T]) Where

func (q EnumeratorAny[T]) Where(predicate func(T) bool) EnumeratorAny[T]

Where filters an enumeration based on a predicate function. This operation returns elements that satisfy the specified condition.

The where operation will: - Apply the predicate function to each element in the enumeration - Yield only elements for which the predicate returns true - Preserve the original order of elements that pass the filter - Handle nil enumerators gracefully - Support early termination when consumer returns false

Parameters:

predicate - a function that determines whether to include an element

Returns:

An EnumeratorAny[T] that yields elements satisfying the predicate

Notes: - If the original enumerator is nil, returns an empty enumerator - Lazy evaluation - elements are processed and filtered during iteration - No elements are buffered - memory efficient - The enumeration stops when the source is exhausted or consumer returns false - Predicate function should be pure (no side effects) for predictable behavior - Elements for which predicate returns false are simply skipped

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL