概要
C#のListをどうやって並び替えていますか?
数字や文字列以外にStruct(構造体)など、各種ジェネリックでも対応可能な方法について解説します。
前提環境
- Windows 10
- Visual Studio Professional 2019
- .NET Framework 4.2
- C#
コードのポイント
- ListはSortメソッドで並び替えが可能です。
- Sortメソッドを使用すると、そのオブジェクトList自体が並び変えられます。
(他の変数に代入したい場合はOrderByメソッドなどを使用します。) - compareToメソッドがある型を並び替える場合、Sortは引数無しでOKです。
(正確にはIComparableインターフェースのある型) - compareToメソッドが無い場合、ラムダ式で比較内容を記載すると楽ちんです。(サンプルコード参照。)
サンプルコード
int(数値)のListの場合
List<int> intList = new List<int>();
// 追加は省略
intList.Sort(); // Sortを引数無しで呼び出す。
string(文字列)のListの場合
List<string> stringList = new List<string>();
// 追加は省略
stringList.Sort(); // Sortを引数無しで呼び出す。
Struct(構造体)のListの場合
// 下記のような構造体をdisplayNameで並び替える。
struct TestStruct
{
public string name;
public string displayName;
public string description;
}
// 追加は省略
List<TestStruct> stList = new List<TestStruct>();
// Sort引数の中身をラムダ式で表現する。
// 以下の例はdisplayNameで並び替えを行っています。
// 今回のラムダ式の詳しい解説は下記に記載しています。
stList.Sort((a, b) => a.displayName.CompareTo(b.displayName));
ラムダ式の簡単な解説
そもそもSortの()の中には何を書くの?
- マニュアルを参照すると4種類ぐらいありますが、今回紹介しているのは「Comparison<T>」です。
- 「Comparison<T>」とは同じ型の 2 つのオブジェクトを比較する「メソッド」を表します。
- そうです。「メソッド」を引数にするのです。普段、数字や文字列ばかりだと慣れないかもしれませんが、「メソッド」も引数にできるのです。
- で、「Comparison<T>」ですが、「public delegate int Comparison<in T>(T x, T y);」というメソッドで、引数が2つ、返り値がint型のメソッドです。
- Microsoftのマニュアル
なんでラムダ式?矢印の左のカッコと右側って何?
- ラムダ式は「メソッド」の1つです。なので、Sortの()の「Comparison<T>」として書くことができます。
- 「=>」の左が引数で、右側が処理内容です。
- (a, b)なので、引数が2つです。右側の「a.displayName.CompareTo(b.displayName)」が処理内容です。本来なら{}で囲んで、returnも付ける必要がありますが、1行だけの場合はどちらも省略可能です。
- つまり引数が2つで戻り値がint(compreToの結果を返す)ので、「public delegate int Comparison<in T>(T x, T y);」と一致したメソッドになります。
それはわかったけど戻り値と並び替えの関係性は?
「public delegate int Comparison<in T>(T x, T y);」の戻り値intと、並び替えの関係ですが以下のようになります。
戻り値 | 意味 |
---|---|
0より小さい | 引数aは引数bよりも小さい(昇順の並び替えで上にくる) |
0 | 引数aは引数bと同じ大きさ。並び替えない |
0より大きい | 引数aは引数bよりも大きい(昇順の並び替えで下にくる) |