C# Linq:将几个GroupBy的结果分组
我有两个GroupBy的结果:C# Linq:将几个GroupBy的结果分组,c#,linq,group-by,C#,Linq,Group By,我有两个GroupBy的结果: IEnumerable<IGrouping<long, MyClass>> result1 = ...; IEnumerable<IGrouping<long, MyClass>> result2 = ...; 具有相同键的项在结果序列中被提及两次。显然,我需要一个特殊的Concat用于I分组,如下所示: public static IEnumerable<IGrouping<TKey, TSource
IEnumerable<IGrouping<long, MyClass>> result1 = ...;
IEnumerable<IGrouping<long, MyClass>> result2 = ...;
具有相同键的项在结果序列中被提及两次。显然,我需要一个特殊的Concat
用于I分组
,如下所示:
public static IEnumerable<IGrouping<TKey, TSource>> Concat<TSource, TKey>
(this IEnumerable<IGrouping<TKey, TSource>> first,
IEnumerable<IGrouping<TKey, TSource>> second)
return first.Concat(second)
.GroupBy(g => g.Key, (key, gg) => Grouping.Create(key, gg.SelectMany(g => g)));
公共静态IEnumerable Concat
(首先,
(可数秒)
我可以将组中的所有元素解组并重新分组,但这当然是一种浪费
我已经看过了。该方法创建GroupedEnumerable对象,该对象将在枚举GroupedEnumerable后立即创建查找对象
我应该做类似的事情,还是有更好(更容易掌握)的方法?使用
Concat
然后使用GroupBy
并使用SelectMany
将每个结果分组展平相对容易
问题是如何将其转换为IGrouping
,因为没有实现该接口的公共标准类,它是由GroupBy
和ToLookup
实现返回的,并且没有GroupBy
重载来允许我们需要的内容。因此,我们需要自己实现,幸运的是,这很简单:
class Grouping<TKey, TElement> : IGrouping<TKey, TElement>
{
IEnumerable<TElement> elements;
public Grouping(TKey key, IEnumerable<TElement> elements)
{
this.Key = key;
this.elements = elements;
}
public TKey Key { get; }
public IEnumerator<TElement> GetEnumerator() => elements.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
public static class Grouping
{
public static IGrouping<TKey, TElement> Create<TKey, TElement>(TKey key, IEnumerable<TElement> elements) =>
new Grouping<TKey, TElement>(key, elements);
}
这种方法有效。甚至比我使用的方法更快(创建一个dictionaryHi Harald,这只是为了方便起见,类似于
Tuple.create
,以便让编译器推断泛型参数。当然,如果您愿意,您可以直接使用构造函数。
return first.Concat(second)
.GroupBy(g => g.Key, (key, gg) => Grouping.Create(key, gg.SelectMany(g => g)));