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.

Advertisements

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

iReadable { }

.NET Tips & Tricks

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

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

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: