LINQ – Grouping Feature

I have a love affair… no, not that kind – the LINQ kind  🙂   It makes what is normally ‘complex’ – into fun and rather easy to do.

Let’s take sorting.

ie. I have a list of many items from a database table that I retrieve.  Then I need to group all the ‘same types’ so I can do some reporting on them.

I run a fun aircraft ww2 flight sim website for flight simulator game ‘IL2: Sturmovik’.  I was asked recently to show the ‘kills to death’ ratio of the different aircraft flown by the pilots in this sim.

My database stores a list of these air summaries per mission – so you might have something like this:

KillerClass KilledClass

FW190       Spitfire

FW190       P47

P47           109

 

So the first step is to ‘group’ the Aircraft – do a ‘kill count’:

IEnumerable<IGrouping<string, MisAirSummary>> AirSummaryByKillerClass = airSummary.GroupBy(a => a.KillerClass);

(where airSummary is the results from my LINQ Query – a List<MisAirSummary>)

Simple!

So, how do I display the results?  (Note, in this sample I break some ‘Business layer’ vs. ‘UI Layer’ concepts… but that isn’t the topic is it…  😉 )

(I’m using ASP.NET MVC…)

I pass the two collections down to the view in the ViewData (normally I wouldn’t do it this way, but this is a quick and dirty sample)

note the ‘foreach (var items in AirSummaryByKillerClass.OrderBy(p => p.Key))’  line below.  Each ‘items’ is a

System.Linq.Lookup<string,FSData.MisAirSummary>.Grouping :

the AirSummaryByKillerClass is a :

{System.Linq.GroupedEnumerable<FSData.MisAirSummary,string,FSData.MisAirSummary>}

The ‘items.Key’ is the grouped by value, and has a list of the values.  Note is it using the ‘Lookup’ feature of Linq. 

 

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<%
    List<FSData.MisAirSummary> airSummary = ViewData["AirSummary"] as List<FSData.MisAirSummary>;
    IEnumerable<IGrouping<string, FSData.MisAirSummary>> AirSummaryByKillerClass = ViewData["AirSummaryByKillerClass"] as IEnumerable<IGrouping<string, FSData.MisAirSummary>>; %>



    <br /><br />
    <table id="stats" class="tablesorter" style="width:600px">
    <thead>
        <tr>
            <th>Type</th>
            <th>Kills</th>
            <th>Deaths</th>
            <th>K/D Ratio (x/1)</th>
        </tr>
    </thead>
    <tbody>
<% foreach (var items in AirSummaryByKillerClass.OrderBy(p => p.Key))
   { %>

            <tr>
            <td>
                <%
                    int kills = items.Count();
                    int deaths = airSummary.Where(s => s.KilledClass == items.Key).Count();
                    float kdRatio = 0.0F;
                    if (deaths != 0) { kdRatio = float.Parse(kills.ToString()) / float.Parse(deaths.ToString()); }
                %>
                <b><%= items.Key %> </b>

            </td>
            <td><%= kills.ToString() %></td>
            <td><%= deaths.ToString() %></td>
            <td><%= kdRatio.ToString("F")%></td>
            </tr>

<%} %></tbody> </table>
</asp:Content>
So there you have it - quite easy to implement!  (see it in action...) LINQ does the hard work for me, so I can just solve the problem at hand.
Advertisements

2 thoughts on “LINQ – Grouping Feature

  1. or…

    ViewData[“AirSummaryByKillerClass”] = _
    from s in airSummary
    group s by s.KillerClass into groups
    select new { groups.Key, Kills = groups.Count(), Deaths = airSummary.Count(d => d.KilldClass == groups.Key) };

    /*…now your foreach content only needs this: */

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s