C#
List Sorting
Multi-level Sorting
Programming
.NET

C List Sort by x then y

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Sorting by x and then by y is a standard multi-key sort: compare x first, and only if two items have the same x, compare y. In C#, you can do this either in place with List<T>.Sort or by creating a new ordered sequence with LINQ.

Sort In Place With List<T>.Sort

If you already have a List<T> and want to reorder that list directly, use Sort with a comparison lambda.

csharp
1using System;
2using System.Collections.Generic;
3
4public record Point(int X, int Y);
5
6var points = new List<Point>
7{
8    new(2, 5),
9    new(1, 9),
10    new(2, 1),
11    new(1, 3)
12};
13
14points.Sort((a, b) =>
15{
16    int byX = a.X.CompareTo(b.X);
17    if (byX != 0)
18        return byX;
19
20    return a.Y.CompareTo(b.Y);
21});
22
23foreach (var point in points)
24    Console.WriteLine(point);

The comparison logic reads naturally:

  1. Compare X
  2. If X differs, return that result
  3. Otherwise compare Y

That is the direct answer to "sort by x then y."

Use LINQ When You Want a New Sequence

If you prefer a more declarative style, or you do not want to mutate the original list, use OrderBy and ThenBy.

csharp
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5public record Point(int X, int Y);
6
7var points = new List<Point>
8{
9    new(2, 5),
10    new(1, 9),
11    new(2, 1),
12    new(1, 3)
13};
14
15var sorted = points
16    .OrderBy(p => p.X)
17    .ThenBy(p => p.Y)
18    .ToList();
19
20foreach (var point in sorted)
21    Console.WriteLine(point);

This is often the most readable version, especially when the sort rules get longer or when you are already writing a LINQ pipeline.

Choose Between Sort and LINQ

The two approaches solve slightly different problems:

  • 'List<T>.Sort mutates the existing list'
  • 'OrderBy(...).ThenBy(...) creates a new ordered sequence'

Use Sort when you care about avoiding an extra list allocation or you explicitly want the original list reordered. Use LINQ when clarity matters more or when immutability is helpful.

Sort Descending on the Secondary Key

You can vary the secondary rule easily. For example, sort by X ascending and Y descending:

csharp
1var sorted = points
2    .OrderBy(p => p.X)
3    .ThenByDescending(p => p.Y)
4    .ToList();

The same pattern scales to three or more keys with additional ThenBy or ThenByDescending calls.

Use a Reusable Comparer When the Rule Matters

If the same sort rule appears in multiple places, extract it into an IComparer<T> instead of repeating lambdas everywhere.

csharp
1using System.Collections.Generic;
2
3public sealed class PointComparer : IComparer<Point>
4{
5    public int Compare(Point? a, Point? b)
6    {
7        if (ReferenceEquals(a, b)) return 0;
8        if (a is null) return -1;
9        if (b is null) return 1;
10
11        int byX = a.X.CompareTo(b.X);
12        return byX != 0 ? byX : a.Y.CompareTo(b.Y);
13    }
14}

That is useful when the rule is part of the domain rather than a one-off call-site detail.

Common Pitfalls

  • Returning only a.X.CompareTo(b.X) sorts by x alone and ignores y ties.
  • Assuming OrderBy modifies the original list is incorrect; it returns a new sequence.
  • Mixing ascending and descending requirements without being explicit can produce subtle ordering bugs.
  • Writing complex comparison logic inline everywhere makes code harder to maintain. Extract a comparer if the rule is reused.

Unit tests are especially helpful when multi-key sort rules become part of business logic.

Summary

  • To sort by x then y, compare x first and use y only as the tie-breaker.
  • Use List<T>.Sort for in-place sorting.
  • Use OrderBy(...).ThenBy(...) when you want a new sorted sequence.
  • The same multi-key pattern extends naturally to additional sort fields.

Course illustration
Course illustration

All Rights Reserved.