【C#】Array.SortとComparisonで配列をカスタム順序(文字列長など)で並べ替える方法

目次

Array.Sortの標準動作とその限界

Array.Sort(array)メソッドは、配列の要素を「昇順」に並べ替えるための非常に便利な静的メソッドです。

  • int型なら数値の小さい順(1, 5, 10
  • string型なら辞書順("A", "B", "C"

しかし、もし「文字列を長さの短い順に並べ替えたい」や、「数値を絶対値の小さい順に並べ替えたい」といった、デフォルト以外の独自の(カスタム)ルールでソートしたい場合、Array.Sort(array)だけでは対応できません。

このような場合、Array.Sortのオーバーロード(引数が異なる同名メソッド)に、Comparison<T>デリゲート(比較メソッド)を渡すことで、ソートロジックを自由に定義できます。


Comparison<T> デリゲートとは

Comparison<T>は、2つの同じ型(T)のオブジェクト(ab)を受け取り、それらの大小関係をint(整数)で返すメソッドの「型」を定義するデリゲートです。

戻り値のルール: Comparison<T>デリゲート(またはラムダ式)は、以下のルールに従ってint型の値を返す必要があります。

  • 負の値(0 未満): ab よりも小さい(ab よりもに並べる)。
  • ゼロ(0: ab は等しい(順序は問わない)。
  • 正の値(0 より大きい): ab よりも大きい(ab よりもに並べる)。

このルールは、int型やstring型が持つCompareToメソッドの戻り値と一致しています。


コード例1:string配列を「長さ順」でソート(昇順・降順)

Array.Sortの第2引数に、この比較ルールを実装した「ラムダ式」を渡すのが最も一般的な方法です。

CompareToメソッドを活用すると、このロジックを簡単に実装できます。

using System;

public class SortByLengthExample
{
    public static void Main()
    {
        string[] fileNames = { "report-2025.pdf", "data.csv", "summary.txt", "archive.zip" };

        Console.WriteLine("--- 元の順序 ---");
        PrintArray(fileNames);

        // --- 1. 昇順(長さの短い順)でソート ---
        // (a, b) => a.Length.CompareTo(b.Length)
        // a.Length が b.Length より短ければ負、長ければ正が返る
        Array.Sort(fileNames, (a, b) => a.Length.CompareTo(b.Length));
        
        Console.WriteLine("\n--- 長さ昇順 (短い順) ---");
        PrintArray(fileNames);

        // --- 2. 降順(長さの長い順)でソート ---
        // (a, b) => b.Length.CompareTo(a.Length)
        // a と b の比較ロジックを逆転させる
        Array.Sort(fileNames, (a, b) => b.Length.CompareTo(a.Length));

        Console.WriteLine("\n--- 長さ降順 (長い順) ---");
        PrintArray(fileNames);
    }

    private static void PrintArray(string[] arr)
    {
        foreach (var item in arr)
        {
            Console.WriteLine(item);
        }
    }
}

出力結果:

--- 元の順序 ---
report-2025.pdf
data.csv
summary.txt
archive.zip

--- 長さ昇順 (短い順) ---
data.csv
summary.txt
archive.zip
report-2025.pdf

--- 長さ降順 (長い順) ---
report-2025.pdf
archive.zip
summary.txt
data.csv

コード例2:int配列を「絶対値」でソート

この手法は、string型だけでなく、あらゆる型の配列に適用できます。int配列を、数値の大小ではなく「絶対値(0からの距離)」で並べ替える例です。

using System;

public class SortByAbsoluteValueExample
{
    public static void Main()
    {
        int[] numbers = { 10, -50, 2, -100, 30 };

        Console.WriteLine("--- 元の順序 ---");
        PrintArray(numbers);
        
        // Math.Abs() で絶対値を取得し、それを比較する
        Array.Sort(numbers, (a, b) => Math.Abs(a).CompareTo(Math.Abs(b)));

        Console.WriteLine("\n--- 絶対値の昇順 ---");
        PrintArray(numbers); // 2, 10, 30, -50, -100 (の順)
    }
    
    private static void PrintArray(int[] arr)
    {
        foreach (var item in arr) Console.Write($"[{item}] ");
        Console.WriteLine();
    }
}

出力結果:

--- 元の順序 ---
[10] [-50] [2] [-100] [30] 

--- 絶対値の昇順 ---
[2] [10] [30] [-50] [-100] 

(注: 2 (絶対値2) が -100 (絶対値100) より先に来ています。)


補足:Comparison<T>デリゲート変数

もし比較ロジックが複雑で、ラムダ式では読みにくい場合、ロジックをComparison<T>デリゲート型の変数として切り出すことができます。

using System;

public class SortWithDelegateExample
{
    public static void Main()
    {
        string[] fileNames = { "report-2025.pdf", "data.csv", "summary.txt" };

        // 比較ロジックをデリゲート変数に格納
        Comparison<string> lengthComparer = (a, b) => a.Length.CompareTo(b.Length);

        // Sort メソッドにその変数を渡す
        Array.Sort(fileNames, lengthComparer);

        foreach (var item in fileNames)
        {
            Console.WriteLine(item);
        }
    }
}

まとめ

Array.Sortメソッドの第2引数にComparison<T>デリゲート(通常はラムダ式)を渡すことで、配列の並べ替えルールを自由に定義(カスタマイズ)できます。

比較ロジックは「abより先なら負、後なら正」という規約に従う必要がありますが、CompareToメソッドを利用することで、昇順・降順のロジックを簡潔かつ安全に記述できます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次