Linq:将几个GroupBy

时间:2016-12-06 09:31:21

标签: c# linq group-by

我有两个GroupBy的结果:

IEnumerable<IGrouping<long, MyClass>> result1 = ...;
IEnumerable<IGrouping<long, MyClass>> result2 = ...;

我想将它们组合成一个序列。 result2中的某些元素可能具有也是result1中的键的IGrouping键。所以标准Enumerable.Concat不起作用:

IEnumerable<IGrouping<long, MyClass>> result = result1.Concat(result2);

在结果序列中提到两次具有相同键的项目。显然我需要Concat IGrouping<TKey, TSource>这样的特殊public static IEnumerable<IGrouping<TKey, TSource>> Concat<TSource, TKey> (this IEnumerable<IGrouping<TKey, TSource>> first, IEnumerable<IGrouping<TKey, TSource>> second)

 fetch(apiUrl, {
    method: method,
    headers: headersIfAny,
    body: theDataToSend
  })
  .then(response => /* do something with response */)
  .catch(err => /* do something with err */);

我可以取消组合该组的所有元素并再次对它们进行分组,但这当然是浪费。

我看过source code of Enumerable.GroupBy。该方法创建一个GroupedEnumerable对象,该对象将创建一个Lookup对象,就像枚举GroupedEnumerable一样。

我应该做类似的事情,还是有更好的(更容易掌握)方法?

1 个答案:

答案 0 :(得分:1)

使用Concat后跟GroupBy并使用SelectMany展平每个结果分组,可以相对轻松地获得所需的结果。

问题是如何将其转换为IGrouping<TKey, TElement>,因为没有公共标准类实现该接口,它由GroupByToLookup实现返回,并且还有没有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);
}

现在有问题的方法的实现可能是这样的:

return first.Concat(second)
    .GroupBy(g => g.Key, (key, gg) => Grouping.Create(key, gg.SelectMany(g => g)));