mirror of
https://github.com/CommunityToolkit/dotnet.git
synced 2026-10-25 17:39:38 +08:00
74 lines
3.1 KiB
C#
74 lines
3.1 KiB
C#
// Licensed to the .NET Foundation under one or more agreements.
|
|
// The .NET Foundation licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
// This file is ported and adapted from ComputeSharp (Sergio0694/ComputeSharp),
|
|
// more info in ThirdPartyNotices.txt in the root of the project.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using CommunityToolkit.Mvvm.SourceGenerators.Helpers;
|
|
using Microsoft.CodeAnalysis;
|
|
|
|
namespace CommunityToolkit.Mvvm.SourceGenerators.Extensions;
|
|
|
|
/// <summary>
|
|
/// Extension methods for <see cref="IncrementalValuesProvider{TValues}"/>.
|
|
/// </summary>
|
|
internal static class IncrementalValuesProviderExtensions
|
|
{
|
|
/// <summary>
|
|
/// Groups items in a given <see cref="IncrementalValuesProvider{TValue}"/> sequence by a specified key.
|
|
/// </summary>
|
|
/// <typeparam name="TLeft">The type of left items in each tuple.</typeparam>
|
|
/// <typeparam name="TRight">The type of right items in each tuple.</typeparam>
|
|
/// <typeparam name="TKey">The type of resulting key elements.</typeparam>
|
|
/// <typeparam name="TElement">The type of resulting projected elements.</typeparam>
|
|
/// <param name="source">The input <see cref="IncrementalValuesProvider{TValues}"/> instance.</param>
|
|
/// <param name="keySelector">The key selection <see cref="Func{T, TResult}"/>.</param>
|
|
/// <param name="elementSelector">The element selection <see cref="Func{T, TResult}"/>.</param>
|
|
/// <returns>An <see cref="IncrementalValuesProvider{TValues}"/> with the grouped results.</returns>
|
|
public static IncrementalValuesProvider<(TKey Key, EquatableArray<TElement> Right)> GroupBy<TLeft, TRight, TKey, TElement>(
|
|
this IncrementalValuesProvider<(TLeft Left, TRight Right)> source,
|
|
Func<(TLeft Left, TRight Right), TKey> keySelector,
|
|
Func<(TLeft Left, TRight Right), TElement> elementSelector)
|
|
where TLeft : IEquatable<TLeft>
|
|
where TRight : IEquatable<TRight>
|
|
where TKey : IEquatable<TKey>
|
|
where TElement : IEquatable<TElement>
|
|
{
|
|
return source.Collect().SelectMany((item, token) =>
|
|
{
|
|
Dictionary<TKey, ImmutableArray<TElement>.Builder> map = new();
|
|
|
|
foreach ((TLeft, TRight) pair in item)
|
|
{
|
|
TKey key = keySelector(pair);
|
|
TElement element = elementSelector(pair);
|
|
|
|
if (!map.TryGetValue(key, out ImmutableArray<TElement>.Builder builder))
|
|
{
|
|
builder = ImmutableArray.CreateBuilder<TElement>();
|
|
|
|
map.Add(key, builder);
|
|
}
|
|
|
|
builder.Add(element);
|
|
}
|
|
|
|
token.ThrowIfCancellationRequested();
|
|
|
|
ImmutableArray<(TKey Key, EquatableArray<TElement> Elements)>.Builder result =
|
|
ImmutableArray.CreateBuilder<(TKey, EquatableArray<TElement>)>();
|
|
|
|
foreach (KeyValuePair<TKey, ImmutableArray<TElement>.Builder> entry in map)
|
|
{
|
|
result.Add((entry.Key, entry.Value.ToImmutable()));
|
|
}
|
|
|
|
return result;
|
|
});
|
|
}
|
|
}
|