To sort a list, except for the first element, you need to:
- Separate the first element from the rest of the elements.
- Sort the rest of the elements.
- 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'c
Code 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 method | What 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. |