
.NET 3.5+LINQ Grouping
The sixth part of the LINQ to Objects tutorial examines grouping using the GroupBy standard query operator and equivalent query expression syntax. These allow a collection to be divided into smaller collections, each of which shares a common key.
Grouping Data
LINQ provides the ability to organise information into groups. Using either the standard query operators or query expression syntax, you can specify a key based upon the data held in a collection. The source data is then segregated into several enumerable lists, each containing all of the items with a matching key. For example, you may group a collection of stock items by their categories. The result is a group of collections, one for each unique category, each containing all of the products in that category.
Grouping of data has many uses. You may decide to group a large data set and display one group at a time through the user interface. The user may be able to change the visible group using a combo box or selection of radio buttons. You may also group the information so that you can aggregate the data, obtaining sums, averages or other aggregations for each group.
GroupBy Standard Query Operator
We will begin by examining the GroupBy standard query operator. This is an extension method of the IEnumerable<T> interface that performs grouping. Before we can begin, we need a class to work with. This will be the same StockItem type that we used in the LINQ Results Ordering article:
public class StockItem
{
public string Name { get; set; }
public string Category { get; set; }
public double Price { get; set; }
public StockItem(string name, string category, double price)
{
Name = name;
Category = category;
Price = price;
}
public override string ToString()
{
return string.Format("{0}/{1}/{2}", Name, Category, Price);
}
}
For each example we will use the same stock item source data. To initialise the collection use the following code:
var stock = new List<StockItem>
{
new StockItem("Apple", "Fruit", 0.30),
new StockItem("Banana", "Fruit", 0.35),
new StockItem("Orange", "Fruit", 0.29),
new StockItem("Cabbage", "Vegetable", 0.49),
new StockItem("Carrot", "Vegetable", 0.29),
new StockItem("Lettuce", "Vegetable", 0.30),
new StockItem("Milk", "Dairy", 1.12)
};
27 July 2010