IEnumerable Extensions

LINQ gives you the essential higher-order functions over IEnumerable<T>: Select, Where, SelectMany, Aggregate, and a few dozen more. Funcky adds the ones that are missing, and replaces the ones that return null, default or throw with variants that return an Option<T>.

All of them live in Funcky.Extensions.EnumerableExtensions, which is imported automatically when FunckyImplicitUsings is on. Most of them are lazy, in the same way LINQ's own operators are: nothing happens until the result is enumerated, and the input is enumerated at most once. The exceptions are noted on each operation's page.

Operations marked with ⁂ have an asynchronous counterpart on IAsyncEnumerable<T>, in Funcky itself on .NET 10 and in the Funcky.Async package on older targets.

Finding one element

The …OrNone family: like …OrDefault, but with an unambiguous answer for "nothing found". See Finding one element.

OperationDescription
FirstOrNone ⁂The first element, or the first matching a predicate
LastOrNone ⁂The last element, or the last matching a predicate
SingleOrNone ⁂The only element; throws if there is more than one
ElementAtOrNone ⁂The element at an index, also from the end
MinOrNone ⁂The smallest element or key
MaxOrNone ⁂The largest element or key
MinByOrNoneThe element with the smallest key
MaxByOrNoneThe element with the largest key
AverageOrNone ⁂The arithmetic mean
GetNonEnumeratedCountOrNoneThe count, if it is known without enumerating

Grouping and windowing

Operations that cut one sequence into several. See Grouping and windowing.

OperationDescription
Chunk ⁂Consecutive pieces of a fixed size
SlidingWindow ⁂Overlapping windows of a fixed width
Pairwise ⁂Each element together with its successor
AdjacentGroupBy ⁂Group runs of consecutive elements with the same key
Split ⁂Cut at every occurrence of a separator
TakeEvery ⁂Every n-th element
Transpose ⁂Swap rows and columns of a sequence of sequences
PowerSet ⁂All subsets

Combining sequences

Operations that take several sequences and produce one. See Combining sequences.

OperationDescription
Merge ⁂Merge sorted sequences, keeping them sorted
Interleave ⁂Alternate elements from several sequences
Intersperse ⁂Put a separator element between every two elements
ZipLongest ⁂Zip two sequences without truncating the longer one
FlattenConcatenate a sequence of sequences
CartesianProductAll pairs, as a recipe with SelectMany

Context for each element

Operations that pair every element with information about its position. See Context for each element.

OperationDescription
WithIndex ⁂Each element with its zero-based index
WithFirst ⁂Each element with a flag telling whether it is the first
WithLast ⁂Each element with a flag telling whether it is the last
WithPrevious ⁂Each element with its predecessor as an Option
InclusiveScan, ExclusiveScan ⁂Running aggregate, like Aggregate yielding every intermediate

Filtering and partitioning

See Filtering and partitioning.

OperationDescription
WhereSelect ⁂Select with an Option-returning selector, dropping the Nones
WhereNotNull ⁂Drop the nulls and narrow the element type
Partition ⁂Split into two lists by a predicate, or by Either/Result case
None ⁂!Any, as a readable name
AnyOrElse ⁂The sequence itself, or a fallback if it is empty

Side effects and evaluation

Operations that run actions, or control when and how often the input is enumerated. See Side effects and evaluation.

OperationDescription
ForEachRun an action for each element, eagerly
Inspect ⁂Run an action for each element as it passes through, lazily
InspectEmpty ⁂Run an action if the sequence turns out to be empty
Materialize ⁂Evaluate once into a collection, unless it already is one
Memoize ⁂Evaluate lazily, but at most once, even for several consumers
Shuffle ⁂A random permutation

Strings and monads

See Strings and monads.

OperationDescription
JoinToString ⁂string.Join as an extension
ConcatToString ⁂string.Concat as an extension
Sequence ⁂Turn a sequence of Option/Result/Either inside out
Traverse ⁂Select with a monadic selector, then Sequence