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