C# Tips | コレクション・LINQ:逆順ソート

C# C#
スポンサーリンク

はじめに:「逆順ソート」は“優先度の高いものを先頭に持ってくる技”

業務システムでは「新しい順」「金額の大きい順」「重要度の高い順」のように、“大きいほう・新しいほうを先頭にしたい”場面がとても多いです。
これが「逆順ソート(降順ソート)」です。

C# では、
昇順用の OrderBy に対して、逆順用の OrderByDescending
並び替えたあとに順番だけひっくり返す Reverse
List 自体を書き換える Sort とカスタム比較

といった道具があります。
ここから、「どれをどう使うと読みやすくて安全か」を、初心者向けにかみ砕いていきます。


基本形:OrderByDescending で“大きいほうから並べる”

数値を大きい順に並べる

一番シンプルな例からいきます。

using System;
using System.Collections.Generic;
using System.Linq;

var numbers = new List<int> { 5, 2, 9, 1, 3 };

var desc = numbers.OrderByDescending(x => x);

foreach (var n in desc)
{
    Console.WriteLine(n); // 9, 5, 3, 2, 1
}
C#

OrderBy(x => x) が「小さい順(昇順)」なのに対して、
OrderByDescending(x => x) は「大きい順(降順)」です。

ここでの重要ポイントは、「元の numbers は書き換わらない」ということです。
OrderByDescending は“並び替えられた新しい列”を返すだけで、元の List はそのままです。

日付を「新しい順」に並べる

業務でよくあるのが、「日付の新しい順」です。

var dates = new List<DateTime>
{
    new DateTime(2026, 2, 10),
    new DateTime(2026, 1, 5),
    new DateTime(2026, 3, 1),
};

var newestFirst = dates.OrderByDescending(d => d);

foreach (var d in newestFirst)
{
    Console.WriteLine(d.ToString("yyyy-MM-dd"));
    // 2026-03-01
    // 2026-02-10
    // 2026-01-05
}
C#

「新しい順=値が大きい順」なので、OrderByDescending がそのまま使えます。


オブジェクトを「特定のプロパティ」で逆順ソートする

売上を「金額の大きい順」に並べる

クラスのリストを逆順ソートするのが、実務ではメインです。

public class Sale
{
    public DateTime Date { get; set; }
    public int Amount { get; set; }      // 金額
    public string Customer { get; set; } = "";
}
C#

データを用意します。

var sales = new List<Sale>
{
    new Sale { Date = new DateTime(2026, 2, 10), Amount = 1000, Customer = "A" },
    new Sale { Date = new DateTime(2026, 2, 11), Amount = 5000, Customer = "B" },
    new Sale { Date = new DateTime(2026, 2, 12), Amount = 3000, Customer = "C" },
};
C#

金額の大きい順に並べたいときは、こう書きます。

var byAmountDesc = sales
    .OrderByDescending(s => s.Amount);

foreach (var s in byAmountDesc)
{
    Console.WriteLine($"{s.Amount}: {s.Customer}");
    // 5000: B
    // 3000: C
    // 1000: A
}
C#

ここでの重要ポイントは、「OrderByDescending の中で“何を基準に逆順にするか”を選ぶ」ということです。
s => s.Amount なら「金額の大きい順」、s => s.Date なら「日付の新しい順」になります。


複数キーでの逆順ソート:ThenBy / ThenByDescending の組み合わせ

「日付の新しい順 → 同じ日付なら金額の大きい順」

よくある要件として、「まず日付の新しい順、その中では金額の大きい順」というような複数条件ソートがあります。

var sorted = sales
    .OrderByDescending(s => s.Date)   // 日付の新しい順
    .ThenByDescending(s => s.Amount); // 同じ日付内では金額の大きい順
C#

OrderByDescending が“第一キー”、
ThenByDescending が“第二キー”です。

もし「日付は新しい順、同じ日付内では金額の小さい順」にしたいなら、こうです。

var sorted = sales
    .OrderByDescending(s => s.Date)
    .ThenBy(s => s.Amount); // 第二キーだけ昇順
C#

ここでの重要ポイントは、「昇順・降順をキーごとに選べる」ということです。
OrderBy / OrderByDescendingThenBy / ThenByDescending を組み合わせて、
“優先順位付きの並び順”を素直に表現できます。


Reverse と逆順ソートの違い

Reverse は「今の順番をひっくり返すだけ」

Reverse() というメソッドもありますが、これは「ソート」ではありません。
「今の順番をそのまま逆にする」だけです。

var numbers = new List<int> { 5, 2, 9 };

var reversed = numbers.AsEnumerable().Reverse();

foreach (var n in reversed)
{
    Console.WriteLine(n); // 9, 2, 5
}
C#

元の順番が「5, 2, 9」なので、その逆が「9, 2, 5」です。
値の大小は一切見ていません。

一方、OrderByDescending(x => x) は「値が大きい順」に並べます。
元の順番がどうであれ、「1, 2, 3, 5, 9」のように“ソートされた状態”になります。

ここでの重要ポイントは、「逆順ソートしたいときは OrderByDescending、単に今の順番をひっくり返したいだけなら Reverse」という使い分けです。


List<T>.Sort で“破壊的に逆順ソート”する

元の List 自体を書き換えてよい場合

LINQ の OrderByDescending は「新しい列を返す」方式でしたが、
List<T>Sort を使うと、「その List 自体を並べ替える」ことができます。

var numbers = new List<int> { 5, 2, 9, 1, 3 };

// 昇順ソート
numbers.Sort();

// 逆順にしたいときは Reverse を組み合わせる
numbers.Reverse();

foreach (var n in numbers)
{
    Console.WriteLine(n); // 9, 5, 3, 2, 1
}
C#

あるいは、比較関数で最初から逆順にしても構いません。

numbers.Sort((x, y) => y.CompareTo(x)); // y と x を逆にすることで降順
C#

ここでの重要ポイントは、「Sort は元の List を壊す(順番を変える)」ということです。
元の順番が必要な場面では、Sort ではなく OrderByDescending を使うほうが安全です。


実務で意識してほしいこと

「何を基準に」「どちら向きに」並べたいかを言葉にする

逆順ソートを書く前に、まず日本語で整理してみてください。

日付の新しい順にしたいのか
金額の大きい順にしたいのか
優先度の高い順にしたいのか

それが決まれば、コードはほぼ自動的に決まります。

日付の新しい順 → OrderByDescending(x => x.Date)
金額の大きい順 → OrderByDescending(x => x.Amount)

という具合です。

「逆順ソート」と「単なる Reverse」を混同しない

「逆順ソート」は“値の大小を見て並べ替える”ことで、
「Reverse」は“今の順番をひっくり返すだけ”です。

すでに昇順ソート済みの List を「降順にしたい」だけなら、
SortReverse の組み合わせでもよいですが、
最初から並び順を決めるなら、OrderByDescending を素直に使うほうが意図が伝わりやすいです。


まとめ:「逆順ソートユーティリティ」は“重要なものを先頭に持ってくるためのレバー”

逆順ソートのポイントを短くまとめると、こうなります。

昇順は OrderBy、逆順は OrderByDescending
複数キーの逆順ソートは、OrderByDescendingThenBy / ThenByDescending の組み合わせで書く。
Reverse は「今の順番をひっくり返すだけ」で、ソートとは別物。
List<T>.Sort は List 自体を書き換えるので、元の順番が不要なときに使う。

この感覚が身につくと、「なんとなく並んでいる一覧」から卒業して、
“業務の意味に沿った順番でデータを並べる”コードが自然に書けるようになります。

タイトルとURLをコピーしました