Sort Lists Efficiently in C# with Lambda Expressions

Sorting lists is a common requirement in C# applications, whether you're working with simple data types or complex objects. While traditional sorting methods like Array.Sort and List<T>.Sort work well, using lambda expressions with LINQ provides a more flexible and readable approach to sorting collections efficiently.

In this blog post, we’ll explore different ways to sort lists in C# using lambda expressions, covering both ascending and descending orders, custom comparisons, and performance considerations. Let’s dive in!

Why Use Lambda Expressions for Sorting in C#?

Lambda expressions provide a concise way to define anonymous functions, making sorting operations more readable and maintainable. Instead of writing a full Comparer<T> implementation, you can pass a lambda function directly to sorting methods like Sort() and OrderBy().

Benefits of using lambda expressions for sorting:

  • Concise syntax – Reduces boilerplate code.

  • Inline definitions – No need to create a separate method.

  • Flexible sorting logic – Easily customize sort orders.

  • Better readability – Clearer and easier to maintain.

Sorting Lists with Lambda Expressions

1. Sorting a List in Ascending Order

Let’s start with a simple example: sorting a list of integers in ascending order using a lambda expression.

List<int> numbers = new List<int> { 5, 2, 8, 1, 3 };
numbers.Sort((x, y) => x.CompareTo(y));

// Output: [1, 2, 3, 5, 8]

Here, we use Sort() with a lambda expression (x, y) => x.CompareTo(y), which compares two numbers and orders them accordingly.

2. Sorting a List in Descending Order

To sort in descending order, simply reverse the comparison:

numbers.Sort((x, y) => y.CompareTo(x));

// Output: [8, 5, 3, 2, 1]

Alternatively, using LINQ:

numbers = numbers.OrderByDescending(x => x).ToList();

Sorting Lists of Complex Objects

When working with lists of objects, sorting requires specifying which property to sort by. Consider the following Person class:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

3. Sorting by a Single Property

Sorting a list of Person objects by Age in ascending order:

List<Person> people = new List<Person>
{
    new Person { Name = "Alice", Age = 30 },
    new Person { Name = "Bob", Age = 25 },
    new Person { Name = "Charlie", Age = 35 }
};

people.Sort((p1, p2) => p1.Age.CompareTo(p2.Age));

// Output: Bob (25), Alice (30), Charlie (35)

Using LINQ:

var sortedPeople = people.OrderBy(p => p.Age).ToList();

4. Sorting by Multiple Properties

For multi-level sorting (e.g., sorting by Age, then Name):

people = people.OrderBy(p => p.Age).ThenBy(p => p.Name).ToList();

For descending order:

people = people.OrderByDescending(p => p.Age).ThenByDescending(p => p.Name).ToList();

Custom Comparisons with Lambda Expressions

For more control over sorting, you can define custom sorting logic within lambda expressions.

5. Case-Insensitive String Sorting

Sorting a list of strings ignoring case:

List<string> names = new List<string> { "Alice", "bob", "charlie", "Bob" };
names.Sort((x, y) => string.Compare(x, y, StringComparison.OrdinalIgnoreCase));

// Output: ["Alice", "bob", "Bob", "charlie"]

6. Sorting Based on String Length

names.Sort((x, y) => x.Length.CompareTo(y.Length));

// Output: ["Bob", "Alice", "charlie"]

Performance Considerations

When sorting large lists, efficiency matters. Here are key points to consider:

  • List.Sort() is an in-place sort with O(n log n) complexity.

  • OrderBy() and OrderByDescending() return new collections and may require additional memory allocation.

  • For performance-critical applications, consider using Span and Parallel Sorting for large datasets.

Example of parallel sorting using PLINQ:

var sortedPeople = people.AsParallel().OrderBy(p => p.Age).ToList();

Conclusion

Using lambda expressions for sorting in C# makes your code more concise, readable, and flexible. Whether you're sorting primitive types or complex objects, lambda expressions help streamline the process while maintaining efficiency.

Key Takeaways:

  • Use Sort() with lambda expressions for in-place sorting.

  • Use OrderBy() and OrderByDescending() for LINQ-based sorting.

  • Leverage ThenBy() for multi-level sorting.

  • Consider performance implications for large collections.

By mastering these techniques, you can write efficient and elegant sorting logic in C# applications. Happy coding!