Class DistinctByTransformer<TSource, TKey>
- Namespace
- Wolfgang.Etl.Transformers
- Assembly
- Wolfgang.Etl.Transformers.dll
A transformer that yields each input item with a unique key, where the key is produced by a caller-supplied selector. Subsequent items whose key has already been seen are dropped.
public sealed class DistinctByTransformer<TSource, TKey> : ITransformAsync<TSource, TSource> where TSource : notnull where TKey : notnull
Type Parameters
TSourceThe type of items in the input sequence. Must be non-null.
TKeyThe type of key used for de-duplication. Must be non-null.
- Inheritance
-
DistinctByTransformer<TSource, TKey>
- Implements
-
ITransformAsync<TSource, TSource>
- Inherited Members
- Extension Methods
Examples
// first occurrence of each customer id
var uniqueCustomers = new DistinctByTransformer<Order, int>(o => o.CustomerId);
// case-insensitive distinct by name
var uniqueNames = new DistinctByTransformer<Person, string>
(
p => p.Name,
StringComparer.OrdinalIgnoreCase
);
Remarks
DistinctByTransformer<TSource, TKey> is the transformer equivalent of LINQ's
Enumerable.DistinctBy (introduced in .NET 6). Keys are compared using either the
supplied IEqualityComparer<T> or Default
if none is provided. Order is preserved: the item bearing the first occurrence of each
key is yielded.
The key selector is synchronous - key extraction is normally a cheap pure function (a
property access, an integer ID, etc.) and an async overload would only add per-item
overhead. If the key requires I/O to compute, project the key in a preceding
SelectTransformer stage and use plain DistinctTransformer<T> on the
result.
Memory footprint: a fresh HashSet<T> of keys is allocated per call to TransformAsync(IAsyncEnumerable<TSource>) and grows in proportion to the number of unique keys in the stream.
Implements only Wolfgang.Etl.Abstractions.ITransformAsync<TSource, TDestination> - no progress, no cancellation, no Skip/Max - to keep the hot loop minimal.
Constructors
DistinctByTransformer(Func<TSource, TKey>)
Initializes a new instance with the given key selector, using Default for key comparison.
public DistinctByTransformer(Func<TSource, TKey> keySelector)
Parameters
keySelectorFunc<TSource, TKey>A function that extracts the comparison key from an input item.
Exceptions
- ArgumentNullException
keySelectoris null.
DistinctByTransformer(Func<TSource, TKey>, IEqualityComparer<TKey>?)
Initializes a new instance with the given key selector and equality comparer.
public DistinctByTransformer(Func<TSource, TKey> keySelector, IEqualityComparer<TKey>? comparer)
Parameters
keySelectorFunc<TSource, TKey>A function that extracts the comparison key from an input item.
comparerIEqualityComparer<TKey>The comparer used to determine key equality. If null, Default is used.
Exceptions
- ArgumentNullException
keySelectoris null.
Methods
TransformAsync(IAsyncEnumerable<TSource>)
Asynchronously yields the first item in items for each unique key
produced by the configured selector, dropping later items with already-seen keys.
public IAsyncEnumerable<TSource> TransformAsync(IAsyncEnumerable<TSource> items)
Parameters
itemsIAsyncEnumerable<TSource>The asynchronous source sequence.
Returns
- IAsyncEnumerable<TSource>
An asynchronous sequence containing the first item per distinct key.
Exceptions
- ArgumentNullException
itemsis null.