Grouping Operators

GroupBy - Simple 1

This sample uses group by to partition a list of numbers by their remainder when divided by 5.

Code:

            public void DataSetLinq40()
            {

                var numbers = testDS.Tables["Numbers"].AsEnumerable();

                var numberGroups = numbers.GroupBy(n => n.Field("number")%5).Select(g => new {Remainder = g.Key, Numbers = g});

                foreach (var g in numberGroups)
                {
                    Log.WriteLine("Numbers with a remainder of {0} when divided by 5:", g.Remainder);
                    foreach (var n in g.Numbers)
                    {
                        Log.WriteLine(n.Field("number"));
                    }
                }
            }

Result:

GroupBy - Simple 2

This sample uses group by to partition a list of words by their first letter.

Code:

            public void DataSetLinq41()
            {

                var words4 = testDS.Tables["Words4"].AsEnumerable();

                var wordGroups = words4.GroupBy(w => w.Field("word")[0]).Select(g => new {FirstLetter = g.Key, Words = g});

                foreach (var g in wordGroups)
                {
                    Log.WriteLine("Words that start with the letter '{0}':", g.FirstLetter);
                    foreach (var w in g.Words)
                    {
                        Log.WriteLine(w.Field("word"));
                    }
                }
            }

Result:

GroupBy - Simple 3

This sample uses group by to partition a list of products by category.

Code:

            public void DataSetLinq42()
            {

                var products = testDS.Tables["Products"].AsEnumerable();

                var productGroups = products.GroupBy(p => p.Field("Category")).Select(g => new {Category = g.Key, Products = g});

                foreach (var g in productGroups)
                {
                    Log.WriteLine("Category: {0}", g.Category);
                    foreach (var w in g.Products)
                    {
                        Log.WriteLine("\t" + w.Field("ProductName"));
                    }
                }
            }

Result:

GroupBy - Nested

This sample uses group by to partition a list of each customer's orders, first by year, and then by month.

Code:

            public void DataSetLinq43()
            {

                var customers = testDS.Tables["Customers"].AsEnumerable();

                var customerOrderGroups =
                    customers.Select(c => new { 
                        CompanyName = c.Field("CompanyName"),
                        YearGroups = c.GetChildRows("CustomersOrders").
                            GroupBy(o => o.Field("OrderDate").Year).
                            Select(yg => new { Year = yg.Key,
                                MonthGroups = yg.GroupBy(o => o.Field("OrderDate").Month).
                                Select(mg => new { 
                                    Month = mg.Key,
                                    Orders = mg
                                })
                            })
                     });

                foreach (var cog in customerOrderGroups)
                {
                    Log.WriteLine("CompanyName= {0}", cog.CompanyName);
                    foreach (var yg in cog.YearGroups)
                    {
                        Log.WriteLine("\t Year= {0}", yg.Year);
                        foreach (var mg in yg.MonthGroups)
                        {
                            Log.WriteLine("\t\t Month= {0}", mg.Month);
                            foreach (var order in mg.Orders)
                            {
                                Log.WriteLine("\t\t\t OrderID= {0} ", order.Field("OrderID"));
                                Log.WriteLine("\t\t\t OrderDate= {0} ", order.Field("OrderDate"));
                            }
                        }
                    }
                }
            }

Result:

GroupBy - Comparer

This sample uses GroupBy to partition trimmed elements of an array using a custom comparer that matches words that are anagrams of each other.

Code:

            public void DataSetLinq44()
            {

                var anagrams = testDS.Tables["Anagrams"].AsEnumerable();

                var orderGroups = anagrams.GroupBy(w => w.Field("anagram").Trim(), new AnagramEqualityComparer());

                foreach (var g in orderGroups)
                {
                    Log.WriteLine("Key: {0}", g.Key);
                    foreach (var w in g)
                    {
                        Log.WriteLine("\t" + w.Field("anagram"));
                    }
                }
            }

Result:

GroupBy - Comparer, Mapped

This sample uses GroupBy to partition trimmed elements of an array using a custom comparer that matches words that are anagrams of each other, and then converts the results to uppercase.

Code:

            public void DataSetLinq45()
            {

                var anagrams = testDS.Tables["Anagrams"].AsEnumerable();

                var orderGroups = anagrams.GroupBy(
                    w => w.Field("anagram").Trim(),
                    a => a.Field("anagram").ToUpper(),
                    new AnagramEqualityComparer()
                    );

                foreach (var g in orderGroups)
                {
                    Log.WriteLine("Key: {0}", g.Key);
                    foreach (var w in g)
                    {
                        Log.WriteLine("\t" + w);
                    }
                }
            }

Result: