Ordering a .NET data sequence with various LINQ operators

A sequence of any object can be easily ordered with the following LINQ operators in .NET:

  • OrderBy
  • ThenBy
  • OrderByDescending
  • ThenByDescending

Consider the following sequence:

string[] bands = { "ACDC", "Queen", "Aerosmith", "Iron Maiden", "Megadeth", "Metallica", "Cream", "Oasis", "Abba", "Blur", "Chic", "Eurythmics", "Genesis", "INXS", "Midnight Oil", "Kent", "Madness", "Manic Street Preachers", "Noir Desir", "The Offspring", "Pink Floyd", "Rammstein", "Red Hot Chili Peppers", "Tears for Fears"					 , "Deep Purple", "KISS"};

The first overload of OrderBy lets you specify the property by which to order the elements and they will be sorted by a default comparer. This is how to order the list of bands by the string length:

IEnumerable<string> ordered = bands.OrderBy(band => band.Length);
foreach (string item in ordered)
{
	Console.WriteLine(item);
}

Order by string length

The second overload of OrderBy lets you specify a comparer which will determine the order of elements. The comparer must implement the IComparer of T interface. Say you’d like to order the bands by the number of consonants in their names. The following comparer would do:

public class ConsonantNumberComparer : IComparer<string>
{
	public int Compare(string x, string y)
	{
		int consonantCountStringOne = GetConsonantCount(x);
		int consonantCountStringTwo = GetConsonantCount(y);

		if (consonantCountStringOne < consonantCountStringTwo) return -1;
		if (consonantCountStringOne > consonantCountStringTwo) return 1;
		return 0;
	}

	private int GetConsonantCount(string input)
	{
		char[] consonants = new char[] { 'b', 'c', 'd', 'f', 'g', 'h','k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'z', 'x', 'y' };
		int count = 0;
		foreach (char c in input.ToLower())
		{
			if (consonants.Contains(c))
			{
				count++;
			}
		}

		return count;
	}
}

You can use this comparer as follows:

IEnumerable<string> ordered = bands.OrderBy(band => band, new ConsonantNumberComparer());
foreach (string item in ordered)
{
	Console.WriteLine(item);
}

Order by number of consonants

You can specify additional ordering rules using the ThenBy operator. The following query will order the items by the comparer we’ve just constructed and then in alphabetical order:

IEnumerable<string> ordered = bands.OrderBy(band => band, new ConsonantNumberComparer()).ThenBy(band => band);
foreach (string item in ordered)
{
	Console.WriteLine(item);
}

Order by string length and alphabetical

Don’t use the OrderBy() operator multiple times like this in order to fulfil what ThenBy is doing:

IEnumerable<string> ordered = bands.OrderBy(band => band, new ConsonantNumberComparer()).OrderBy(band => band);

This will first order the items according to the ConsonantNumberComparer and then completely re-order the items in alphabetical order. Therefore the first order by is cancelled out in the final sequence.

The OrderByDescending and ThenByDescending operators do exactly what OrderBy and ThenBy but in reverse order as the names suggest:

IEnumerable<string> ordered = bands.OrderByDescending(band => band, new ConsonantNumberComparer()).ThenByDescending(band => band);
foreach (string item in ordered)
{
	Console.WriteLine(item);
}

Order by string length and alphabetical descending

ThenBy, OrderByDescending and ThenByDescending can also accept an IComparer object just like OrderBy.

View the list of posts on LINQ here.

Advertisement

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

%d bloggers like this: