Thursday, April 17, 2008

Sorting and Grouping in LINQ to Objects

As a continuation to the articles on LINQ, in this post I will explain how to write queries and use the query operators to perform common operations such as sorting, dealing with nested data, and grouping.

For the examples used in this article I will use the following data model.

public class Customer

{

public String Name { get; set; }

public Int32 Age { get; set; }

public Collection<Address> Addresses { get; set; }

public String Industry { get; set; }

}

public class Address

{

public String AddressLine { get; set; }

public String Country { get; set; }

}

And the method to return the data as

private static Collection<Customer> GetCustomers()

{

return new Collection<Customer> {

new Customer { Name = "John Samuels", Age = 40 , Addresses = new Collection<Address>

{ new Address { AddressLine = "New York", Country = "USA" },

new Address { AddressLine = "California, 21st Main Road", Country = "USA" },

new Address { AddressLine = "London", Country= "UK" }

}, Industry = "Computers"},

new Customer { Name = "Sreejith P.R", Age = 30 , Addresses = new Collection<Address>

{ new Address { AddressLine = "Bangalore", Country = "India" },

new Address { AddressLine = "Redmond", Country = "USA" }

}, Industry = "Telecom"},

new Customer { Name = "Kim David", Age = 35 , Addresses = new Collection<Address>

{ new Address { AddressLine = "Shangai", Country = "China" }

}, Industry = "Telecom"},

new Customer { Name = "Rahul Bose", Age = 50 , Addresses = new Collection<Address>

{ new Address { AddressLine = "New York", Country = "USA" },

new Address { AddressLine = "Bangalore", Country = "India" },

new Address { AddressLine = "Mysore", Country= "India" },

new Address { AddressLine = "Kolkatta", Country= "India" }

}, Industry = "Information Technology"},

new Customer { Name = "Micheal Johnson", Age = 37 , Addresses = new Collection<Address>

{ new Address { AddressLine = "New York", Country = "USA" },

new Address { AddressLine = "London", Country= "UK" }

}, Industry = "Computers"}

};

}

Now let’s say we want to see the customers in USA, sorted by their names in descending order.

The query I wrote to achieve this result is

var customers = (from customer in GetCustomers()

from address in customer.Addresses

where address.Country == "USA"

orderby customer.Name descending

select customer.Name).Distinct();

The operator that we are interested here is the orderby operator which sorts the collection in ascending order by default. You can also use the descending, ThenByDescending, ThenBy, OrderByDescending operators also for sorting.

The groupby operator helps you to group the query result based on any grouping condition.

For example to display all the customers grouped by industry we write the query like.

var industryCustomers =

from customer in GetCustomers()

group customer by customer.Industry into customerIndustries

select new { Industry = customerIndustries.Key, Customers = customerIndustries };

You can also have the advantage of using aggregation operators after grouping the results.

For example to find the minimum age of each customer by each industry we can write the query like.

var industryCustomers =

from customer in GetCustomers()

group customer by customer.Industry into customerIndustries

select new { Industry = customerIndustries.Key, Customers = customerIndustries, MinAge = customerIndustries.Min(cust => cust.Age)};

No comments: