Soenneker.Extensions.Enumerable
4.0.657
Prefix Reserved
dotnet add package Soenneker.Extensions.Enumerable --version 4.0.657
NuGet\Install-Package Soenneker.Extensions.Enumerable -Version 4.0.657
<PackageReference Include="Soenneker.Extensions.Enumerable" Version="4.0.657" />
<PackageVersion Include="Soenneker.Extensions.Enumerable" Version="4.0.657" />
<PackageReference Include="Soenneker.Extensions.Enumerable" />
paket add Soenneker.Extensions.Enumerable --version 4.0.657
#r "nuget: Soenneker.Extensions.Enumerable, 4.0.657"
#:package Soenneker.Extensions.Enumerable@4.0.657
#addin nuget:?package=Soenneker.Extensions.Enumerable&version=4.0.657
#tool nuget:?package=Soenneker.Extensions.Enumerable&version=4.0.657
Soenneker.Extensions.Enumerable
General-purpose extensions for probing, filtering, deduplicating, randomly selecting, hashing, and recursively flattening sequences, plus sequential asynchronous filtering.
Installation
dotnet add package Soenneker.Extensions.Enumerable
Null and emptiness checks
using Soenneker.Extensions.Enumerable;
IEnumerable<string>? values = null;
values.IsNullOrEmpty(); // true
values.Populated(); // false
new[] { "a" }.Empty(); // false
IsNullOrEmpty() and Populated() accept null. Empty() requires a non-null sequence. Each method uses a known collection count when available; otherwise it opens an enumerator and probes one item. Avoid probing a single-use enumerable and then assuming that first item remains available.
GetNonEnumeratedCount() returns a known count without consuming the sequence, or 0 when no count is available. A returned zero is therefore a sizing hint, not proof that an arbitrary enumerable is empty.
Deduplication and null filtering
IEnumerable<string> unique = new[] { "a", "a", "b" }.RemoveDuplicates();
IEnumerable<Person> uniquePeople = people.RemoveDuplicates(person => person.Id);
bool hasDuplicates = people.ContainsDuplicates();
IEnumerable<string>? nonNull = nullableStrings.RemoveNulls();
Deduplication is lazy, uses the default equality comparer, and preserves the first occurrence of each value or selected key. ContainsDuplicates() stops at the first duplicate and returns false for a null source. Both class and nullable-struct sequences have RemoveNulls() overloads; a null source remains null.
Contains(predicate) is an Any-style predicate search with optimized array and list paths. It short-circuits on the first match.
Random selection
string? optional = values.GetRandom();
string required = values.GetRandomStrict();
GetRandom() returns default(T) for null or empty input. That can be indistinguishable from a selected default value. GetRandomStrict() throws for null or empty input. Indexable collections use direct selection; other enumerables are visited once with reservoir sampling. Selection uses the library’s ordinary pseudo-random source and is not suitable for security decisions. Infinite sequences never complete.
Recursive flattening
var root = new Node("root", [new Node("child", [])]);
List<Node> nodes = new[] { root }
.ToFlattenedFromRecursive(node => node.Children)!;
// root, child
Traversal is breadth-first and includes every item in the starting sequence. The returned list is new, but its elements are the original references. Null child collections are treated as empty. The expression overload compiles once per call; prefer the Func overload when the selector can be reused.
The traversal does not detect cycles or repeated nodes. Supply an acyclic tree, or filter visited nodes before using it with a graph.
Asynchronous filtering
List<int> even = await numbers
.WhereAsync(async (number, token) =>
{
await CheckAsync(number, token);
return number % 2 == 0;
}, cancellationToken)
.ToListAsync(cancellationToken);
Task- and ValueTask-based predicates are supported. Items are evaluated sequentially and yielded lazily in source order; this API does not run predicates in parallel.
WhereAsync() treats cancellation through its supplied token as normal early completion. WhereAsyncOrThrow() calls ThrowIfCancellationRequested() and propagates cancellation to the consumer. Predicate failures other than matching cancellation propagate from both variants.
Aggregate hash codes
GetAggregateHashCode() combines each element in enumeration order. By default it also includes the sequence object’s runtime identity, so two separate sequences with equal contents need not match. Pass includeIdentity: false for a content-only hash. Hash codes are process-local and should not be persisted or used as cryptographic digests.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Soenneker.Extensions.Task (>= 4.0.128)
- Soenneker.Extensions.ValueTask (>= 4.0.120)
- Soenneker.Utils.Random (>= 4.0.129)
NuGet packages (13)
Showing the top 5 NuGet packages that depend on Soenneker.Extensions.Enumerable:
| Package | Downloads |
|---|---|
|
Soenneker.Extensions.Enumerable.String
A collection of helpful enumerable string extension methods |
|
|
Soenneker.Dictionaries.SingletonKeys
An externally initializing singleton dictionary that uses double-check asynchronous locking, with optional async and sync disposal |
|
|
Soenneker.Utils.String
A utility library for useful String operations |
|
|
Soenneker.Swashbuckle.Authentication
A middleware implementing basic authentication and RBAC support for Swashbuckle (Swagger) |
|
|
Soenneker.Utils.Network
A utility library of helpful network related operations |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.0.657 | 0 | 8/30/2026 |
| 4.0.656 | 0 | 8/30/2026 |
| 4.0.655 | 127 | 8/30/2026 |
| 4.0.654 | 215 | 8/29/2026 |
| 4.0.653 | 159 | 8/29/2026 |
| 4.0.652 | 41 | 8/29/2026 |
| 4.0.651 | 409 | 8/29/2026 |
| 4.0.650 | 122 | 8/29/2026 |
| 4.0.649 | 28,714 | 8/26/2026 |
| 4.0.648 | 6,583 | 8/25/2026 |
| 4.0.647 | 95,130 | 8/12/2026 |
| 4.0.646 | 115,062 | 7/28/2026 |
| 4.0.644 | 2,020 | 7/28/2026 |
| 4.0.643 | 173 | 7/27/2026 |
| 4.0.642 | 122,737 | 7/18/2026 |
| 4.0.641 | 40,615 | 7/16/2026 |
| 4.0.640 | 1,915 | 7/16/2026 |
| 4.0.638 | 47,153 | 7/14/2026 |
| 4.0.637 | 126,159 | 6/19/2026 |
| 4.0.635 | 1,008 | 6/18/2026 |
Update dependency Soenneker.Extensions.ValueTask to 4.0.120 (#751)