We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I believe for async sequences this can be a good addition to GroupBy method. This method would have the same behavior of python's itertools.groupby
GroupBy
It's also convenient for asynchronous client-side processing of database query when it's guaranteed that elements of the same group are sequential:
return dbContext.Set<DemographicsInPeriod>() .OrderBy(d => d.DemographicsId) .ThenBy(d => d.Period.SequenceNumber) .AsAsyncEnumerable() .GroupSequentialBy(d => d.Demographics, DemographicsByIdEquality, d => d.Period);
Our implementation is the following:
/// <summary> /// Puts consecutive items of the sequence into groups. /// </summary> /// <remarks> /// For example, <c>[1,1,2,1]</c> grouped by value will turn into <strong>three</strong> groups /// with keys <c>[1,2,1]</c>. /// </remarks> public static async IAsyncEnumerable<IGrouping<TKey, TOut>> GroupSequentialBy<TIn, TKey, TOut>( this IAsyncEnumerable<TIn> seq, Func<TIn, TKey> keySelector, IEqualityComparer<TKey> keyEqualityComparer, Func<TIn, TOut> itemSelector) { seq.NotNull(); keySelector.NotNull(); keyEqualityComparer.NotNull(); itemSelector.NotNull(); TKey key; var items = new List<TOut>(); await using var enumerator = seq.GetAsyncEnumerator(); if (!(await enumerator.MoveNextAsync())) { yield break; } key = keySelector(enumerator.Current); items.Add(itemSelector(enumerator.Current)); while (await enumerator.MoveNextAsync()) { var newKey = keySelector(enumerator.Current); var newGroupStarted = !keyEqualityComparer.Equals(key, newKey); var item = itemSelector(enumerator.Current); if (newGroupStarted) { yield return new Grouping<TKey, TOut>(key, items); items = new List<TOut>(); } key = newKey; items.Add(item); } if (items.Count > 0) { yield return new Grouping<TKey, TOut>(key, items); } } private sealed class Grouping<TKey, TElement> : IGrouping<TKey, TElement> { private readonly TKey _key; private readonly IEnumerable<TElement> _elements; public Grouping(TKey key, IEnumerable<TElement> elements) { _key = key; _elements = elements.NotNull(); } public TKey Key => _key; public IEnumerator<TElement> GetEnumerator() => _elements.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => _elements.GetEnumerator(); }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
I believe for async sequences this can be a good addition to
GroupBy
method.This method would have the same behavior of python's itertools.groupby
It's also convenient for asynchronous client-side processing of database query when it's guaranteed that elements of the same group are sequential:
Our implementation is the following:
The text was updated successfully, but these errors were encountered: