C# – Sort all but first element (Linq)

To sort a list, except for the first element, you need to:

  1. Separate the first element from the rest of the elements.
  2. Sort the rest of the elements.
  3. Merge the first element with the sorted list.

This can be accomplished in a single line using Linq methods:

someList.Take(1).Concat(someList.Skip(1).OrderBy(p => p.SomeProperty))
Code language: C# (cs)

I’ll show a full example and explain how this works.

Example – sorting a list of people

Let’s say we have a list of people, such as the following:

var people = new List<Person>()
{             
	new Person()
	{
		FirstName = "Jack",
		LastName = "O'Neill",
		Job = "Commander",
		PetPreference = PetPreference.Dogs
	},
	new Person()
	{
		FirstName = "Teal'c",
		LastName = null,
		Job = "Warrior",
		PetPreference = PetPreference.Cats
	},
	new Person()
	{
		FirstName = "Daniel",
		LastName = "Jackson",
		Job = "Archaeologist",
		PetPreference= PetPreference.Dogs
	},
	new Person()
	{
		FirstName = "Samantha",
		LastName = "Carter",
		Job = "Astrophysicist",
		PetPreference= PetPreference.Cats
	}
};
Code language: C# (cs)

Here’s how to sort the list of people by first name, except for the first person:

foreach(var person in people.Take(1).Concat(people.Skip(1).OrderBy(p => p.FirstName)))
{
	Console.WriteLine(person.FirstName);
}
Code language: C# (cs)

When I run this, I get the following:

Jack
Daniel
Samantha
Teal'cCode language: plaintext (plaintext)

This sorted Daniel, Samantha, and Teal’c in alphabetical order, while keeping Jack in the first position.

How this works

Let’s break the one liner into the 3 steps in the algorithm.

//1. Separate the first element from the rest of the elements
var firstPerson = people.Take(1);
var allButFirstPerson = people.Skip(1);

//2. Sort the remaining elements
var sortedList = allButFirstPerson.OrderBy(p => p.FirstName);

//3. Merge the first element with the sorted list
var firstAndSortedList = firstPerson.Concat(sortedList);
Code language: C# (cs)

This is using the following Linq methods:

Linq methodWhat it does
Take(int N)Returns an IEnumerable with the first N elements.
Skip(int N)Returns an IEnumerable without the first N elements.
OrderBy(lambda)Returns a sorted IEnumerable, using the specified lambda to sort. In the example, it is simply sorting using the FirstName property.
Concat(list)Combines two IEnumerables into a single IEnumerable.

Leave a Comment