简体   繁体   中英

GroupBy and OrderBy

I'm trying to do a GroupBy and then OrderBy to a list I have. Here is my code so far:

reportList.GroupBy(x => x.Type).ToDictionary(y=>y.Key, z=>z.OrderBy(a=>a.Lost));

With the help of the last question I asked on linq I think the ToDictionary is probably unneeded, but without it I don't know how to access the inner value.

To be clear, I need to GroupBy the Type property and want the inner groups I get to be OrderBy the Lost property (an integer). I want to know if there is a better, more efficient way or at the least better then what I've done.

An explanation and not just an answer would be very much appreciated.

Yes, there is better approach. Do not use random names (x,y,z,a) for variables:

reportList.GroupBy(r => r.Type)
          .ToDictionary(g => g.Key, g => g.OrderBy(r => r.Lost));

You can even use long names to make code more descriptive (depends on context in which you are creating query)

reportList.GroupBy(report => report.Type)
          .ToDictionary(group => group.Key, 
                        group => group.OrderBy(report => report.Lost));

Your code does basically the following things:

  1. Group elements by type
  2. Convert the GroupBy result into a dictionary where the values of the dictionary are IEnumerables coming from a call to OrderBy

As far as the code correctness it is perfectly fine IMO, but maybe can be improved in term of efficiency (even if depends on your needs).

In fact, with your code, the values of your dictionary are lazily evaluated each time you enumerate them, resulting in a call to OrderBy method.

Probably you could perform it once and store the result in this way:

var dict = reportList
           .GroupBy(x => x.Type)
           .ToDictionary(y => y.Key, z => z.OrderBy(a => a.Lost).ToList()); 
// note the ToList call

or in this way:

var dict = reportList.OrderBy(a => a.Lost)
                     .GroupBy(x => x.Type)
                     .ToDictionary(y => y.Key, z => z); 
// here we order then we group, 
// since GroupBy guarantees to preserve the original order

Looks fine to me. If you use an anonymous type instead of a Dictionary, you could probably improve the readability of the code that uses the results of this query.

reportList.GroupBy(r => r.Type)
    .Select(g => new { Type = g.Key, Reports = g.OrderBy(r => r.Lost) });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM