Fun With LiNQ Extension Methods!

So I’m not sure how many people have run into this problem, but say you wanted to have a list of arrays grouped by a specific key. For instance, I have a bunch of invoice rows in a table and I want to create a grouping by the Date Created. Before LINQ, you might’ve done something like this:

1
2
3
4
5
6
7
8
9
10
Dictionary <DateTime, List<InvoiceDataRow>> invoiceDictionary =
    new Dictionary<DateTime, List<InvoiceDataRow>>();
foreach(InvoiceDataRow customer in DS.Invoices)
{
    if(invoiceDictionary.ContainsKey(invoice.DateCreated.Date))
        invoiceDictionary[invoice.DateCreated.Date].Add(invoice);
   else
        invoiceDictionary.Add(invoice.DateCreated.Date,
          new List<InvoiceDataRow>(invoice));
}

Thanks to the beauty of LINQ Extension Methods, this can now be summed up in one line:

1
2
IGrouping<DateTime, InvoiceDataRow> groups =
    DS.Invoices.GroupBy(invoice => invoice.DateCreated.Date);

Not only is that handy, but once we have those groups you can do neat operations on them, for instance say you want a sum of all the invoice totals for each date:

1
2
3
4
5
6
foreach(IGrouping<DateTime, InvoiceDataRow> group in groups)
{
    Console.WriteLine(string.Format("Invoice Date: {0}, Total: {1:c}",
        group.Key.ToShortDateString(),
        group.Sum(invoice => invoice.Total)));
}

You can also get to all the individual items in a group just by enumerating through them:

1
2
3
4
5
6
7
8
9
10
foreach(IGrouping<DateTime, InvoiceDataRow> group in groups)
{
    Console.WriteLine(string.Format("Invoices for Date: {0}",
        group.Key.ToShortDateString()));
    foreach(InvoiceDataRow invoice in group)
    {
        Console.WriteLine(string.Format("Invoice ID: {0}",
          invoice.InvoiceID));
    }
}

This will work on pretty much any IEnumerable collection(arrays, lists, arraylists, etc.), all thanks to LINQ Extension Methods!

PS> Thanks to Thu for actually coding this for a commission report in MasterPortal. He’s the one who did all the hard work

Comments