在 LINQ 中分组时如何显式声明类型?

How to explicitly state the types when grouping in LINQ?

我正在玩 GroupBy(...) 我意识到,虽然工作,但我不想使用 var.叫我肛门,但我想知道我有什么类型。 (当然,我不是理论家,当语法让人眼睛流血时,我确实使用 var。不过,知道如何明确化它是件好事,如果有人敦促出现.)

var grouping = array.GroupBy(element => element.DayOfWeek);
foreach (var group in grouping)
{
  Console.WriteLine("Group " + group.Key);
  foreach (var value in group)
    Console.WriteLine(value.Start);
}

根据 intellisense,我正在生成类型为 IGrouping 的东西,但是当我试图明确输入时,奇怪的事情发生了。我已经到达以下位置。

IEnumerable<IGrouping<DayOfWeek, TimeInfo>> grouping 
  = array.GroupBy(element => element.DayOfWeek);
foreach (IGrouping<DayOfWeek, TimeInfo> group in grouping)
{
  Console.WriteLine("Group " + group.Key);
  foreach (TimeInfo value in group)
    Console.WriteLine(value.Start);
}

我的问题是双重的。下面是生成结果的正确且最窄的范围吗?如果没有,我该如何额外收紧它?

但是,如果是这样,我想知道是否有更好的方法来完成该任务。我只需要根据星期几(或实际生产中的任何其他条件)将数组中的元素放入不同的容器中。我真的不需要密钥,只是一种将我的一维数组转换为二维数组的方法。可以说是 SelectMany 的对立面。 (不需要广泛的答案 - 只需一个关键字即可 google。)

Is the below the correct and most narrow scope for the produced result?

好吧,IGrouping<TKey,TElement> 实现了 IEnumerable<TElement> 所以你 可以 做:

IEnumerable<IEnumerable<TimeInfo>> grouping =
  = array.GroupBy(element => element.DayOfWeek);

请注意,数据(包括键值)仍在具体数据结构中;你只是作为一个集合的集合与之交互。

从那里您可以使用 ToArray():

转换为数组
TimeInfo[][] groups = 
   grouping.Select(g => g.ToArray()).ToArray();

我之前就是这样做的,目的是使处理分组的代码更具可读性。通常确保 foreach 或 class 属性 明确声明 IGrouping 的类型,以便类型清晰。如此处所述,没有实现 IGrouping 的具体类型,因此您无法使用更具体的内容,所以我想说,就声明 groupby 的结果而言,您无法做更多的事情来收紧它:Is it possible to create some IGrouping object

您还可以使用 ToDictionary 创建许多开发人员更熟悉的东西,但每个值实际上都是一个列表,这可能有点奇怪。

正如 Stanley 指出的那样,您可以将 Select 与 ToArray 一起使用,或者您可以使用 ToList 创建列表的列表。