BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

LINQ
.NET 3.5+

LINQ Results Ordering

The fifth part of the LINQ to Objects tutorial looks at sorting collections or the results of LINQ queries. This is achieved using the group of five standard query operators that relate to ordering, or the equivalent clauses in query expression syntax.

Using OrderByDescending

OrderByDescending, as you might expect, is identical to OrderBy except that it sorts the results into descending order. The following sample orders by the stock item name using the default comparer:

var results = stock.OrderByDescending(s => s.Name);

/* RESULTS

Orange/Fruit/0.29
Milk/Dairy/1.12
Lettuce/Vegetable/0.3
Carrot/Vegetable/0.29
Cabbage/Vegetable/0.49
Banana/Fruit/0.35
Apple/Fruit/0.3

*/

Using ThenBy

OrderBy and OrderByDescending both apply primary ordering to a collection. Used alone, you can only sort by one value or expression. The ThenBy method allows you to add secondary ordering. The sorting is applied after the OrderBy or OrderByDescending operator and sorts items that are duplicated in the primary sort order. You can include as many secondary ordering operations as required, each refining the results of previous calls.

ThenBy is used in a similar manner to OrderBy. You provide a Func delegate to determine what to sort by and an optional comparer. In the sample below, the default comparer is used for both primary and secondary sorting. The primary operation sorts the results by category name. Where the category names for several items match, the ThenBy call orders the sub-group by name.

var results = stock.OrderBy(s => s.Category).ThenBy(s => s.Name);

/* RESULTS

Milk/Dairy/1.12
Apple/Fruit/0.3
Banana/Fruit/0.35
Orange/Fruit/0.29
Cabbage/Vegetable/0.49
Carrot/Vegetable/0.29
Lettuce/Vegetable/0.3

*/

Using ThenByDescending

ThenByDescending allows you to specify a secondary sort in descending order. The sample below sorts the categories in ascending order first, then the prices in descending order.

var results = stock.OrderBy(s => s.Category).ThenByDescending(s => s.Price);

/* RESULTS

Milk/Dairy/1.12
Banana/Fruit/0.35
Apple/Fruit/0.3
Orange/Fruit/0.29
Cabbage/Vegetable/0.49
Lettuce/Vegetable/0.3
Carrot/Vegetable/0.29

*/

Using Reverse

The fifth, and final, standard query operator that we will examine in this article is Reverse. This method reverses the items in a collection. Unlike the previous methods, Reverse changes the collection directly, rather than returning a new collection. The return type is void.

stock.Reverse();

/* RESULTS

Milk/Dairy/1.12
Lettuce/Vegetable/0.3
Carrot/Vegetable/0.29
Cabbage/Vegetable/0.49
Orange/Fruit/0.29
Banana/Fruit/0.35
Apple/Fruit/0.3

*/

Ordering with Query Expression Syntax

In this section we will recreate some of the above examples using query expression syntax. To specify ordering in a query, the orderby clause is used. This must appear before the projection clause. The orderby clause is provided with the field, property or expression that forms the basis of the sorting operation. This is similar to when using the standard query operators and a lambda expression, except that the lambda operator and parameters are not included.

The first example sorted the stock items by name. In query syntax this becomes:

var results =
    from s in stock
    orderby s.Name
    select s;

In the second example, we added a custom comparer. Unfortunately this is not possible using query expression syntax. All ordering in this style of query uses the default comparer for the data type.

The third example used the OrderByDescending method. To sort in descending order using query syntax, the descending clause is appended to the item being sorted:

var results =
    from s in stock
    orderby s.Name descending
    select s;

There is no specific clause for ThenBy or ThenByDescending. When you wish to apply secondary ordering, you provide the sort expressions as a comma-separated list. The first item in the list is translated to OrderBy and each subsequent item becomes a call to ThenBy. In the earlier example we sorted the stock items by category and name. In query syntax you can use the following code:

var results =
    from s in stock
    orderby s.Category, s.Name
    select s;

In the final standard query operator example we ordered the stock items by category in ascending order and then by price in descending order, using ThenByDescending. When using query expression syntax, the descending clause can be added to each sort criteria individually to mix the two directions:

var results =
    from s in stock
    orderby s.Category, s.Price descending
    select s;
19 July 2010