5

I'm playing around with GroupBy(...) and I realize that, although working, I prefer not to use var. Call me anal but I like to know what type I have when I have it. (Of course, I'm not an ideologue and when the syntax is making ones eyes bleed, I do use var. Still, it's nice to know how to explicitize it, should ones urge emerge.)

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);
}

According to the intellisense, I'm generating something of type IGrouping but when I tried to type that in explicitly, weird stuff happened. I've arrived at the following.

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);
}

My question is twosome. Is the below the correct and most narrow scope for the produced result? If not, how can I tight it up additionally?

If it is so, however, I'd like to know if there's a better way to approach the task. I only need to put my elements from the array into different bins with respect to day of the weeks (or any other condition in the actual production). I don't really need the key, just a way to make my 1D array into 2D array of arrays. Something like an opposite to SelectMany, so to speak. (No extensive answer needed - just a keyword to google away.)

adv12
  • 8,443
  • 2
  • 24
  • 48
Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • @adv It was **supposed** to be derogatory because programming in a certain way just because of some semi-religious conviction tells one to **is** often rather counter-productive. Nevertheless, let's keep your edition, since I don't want to stir up bad emotions. There are better suited places for such. :) – Konrad Viltersten Jun 08 '15 at 22:17

2 Answers2

4

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

Well, IGrouping<TKey,TElement> implements IEnumerable<TElement> so you could do:

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

Note that the data (including the key values) is still in the concrete data structure; you're just interfacing with is as a collection of collections.

From there you can convert to arrays by using ToArray():

TimeInfo[][] groups = 
   grouping.Select(g => g.ToArray()).ToArray();
D Stanley
  • 149,601
  • 11
  • 178
  • 240
1

I have done exactly this before to make code more readable that deals with groupings. Often making sure a foreach or class property declares the types of the IGrouping explicitely so the type is clear. As covered here, there is no concrete type that implements IGrouping, so there is nothing more concrete that you can use, so I would say as far as declaring the result of a groupby, there's nothing more you can do to tighten it down: Is it possible to create some IGrouping object

You can also use ToDictionary to create something that is more familiar to many developers, but each value would actually be a list, which might be a bit odd.

As Stanley points out you can use Select with ToArray, or you can use ToList to create a List of Lists.

Community
  • 1
  • 1
AaronLS
  • 37,329
  • 20
  • 143
  • 202