【C#入門】配列、Listをソートする方法(降順、カスタマイズも解説)

Listや配列のソートって使っていますか?

C#ではListや配列の要素を昇順で並び替えるメソッドが用意されています。また、要素が文字列や日付時刻であっても並び替えることができます。

この記事では、Listや配列のソートについて

  • 配列、Listのソートとは
  • Array.Sortで配列のソート
  • List.SortでListのソート
  • ラムダ式で降順ソート
  • LINQで降順ソート

という基本的な内容から、処理速度の比較や文字列、日付時刻のソート、Comparisonデリゲートでカスタムソート、Compare、CompareToを使用する場合など応用的な内容についても解説していきます。

今回はListや配列のソートについて、使い方をわかりやすく解説します!

配列、Listのソートとは

配列やList型のオブジェクトで要素を順番に並び替えることソートと言います。小さい値から大きい値の順に並べることを昇順、逆に大きい値から小さい値に並べることを降順と言います。

C#では数値の要素に限らず、文字列やDateTime型の日付時刻もソートすることができるメソッドが用意されています。文字列の場合はアルファベット順や五十音順に並び替えます。ソートの方法はいくつかあるので、一つずつ解説していきます!

Array.Sortで配列のソート

Array.Sortで配列をソートする方法についてみていきましょう。Array.Sortメソッドは以下のように定義されています。

引数arrayには、並べ替えの対象となる1次元の配列を指定します。サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、Array.Sortメソッドを使ってint型の配列srcの要素を昇順に並び替えています。

List.SortでListのソート

配列と同じようにList型のオブジェクトもソートすることができます。List型のオブジェクトからSortメソッドを呼び出すことで、昇順に並び替えることができます。サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、まずAddRangeメソッドを使ってList型のオブジェクトlistに配列srcの要素を追加しています。そして、Sortメソッドを使ってlistの要素を昇順に並び替えています。

ラムダ式で降順ソート

List.Sortメソッドの引数にソートの条件をラムダ式で簡単に指定することができます。サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、Sortメソッドの引数にラムダ式を指定しています。

LINQで降順ソート

LINQを使ってソートすることもできます。ソートするにはOrderByメソッドを使用します。サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、OrderByメソッドを使って降順に並び替えています。

処理速度の比較

これまでArray.Sortメソッド、List.Sortメソッド、ラムダ式、LINQそれぞれでソートする方法についてお伝えしてきました。これらの処理速度についてサンプルコードで比較してみましょう。

なお、乱数を使って配列の要素の値を決めて、それを昇順でソートすることにします。サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、それぞれの方法を10万回繰り返すのにかかった時間をDiagnostics.Stopwatchクラスを使って計測しています。Array.Sortメソッドでソートした場合が最も処理速度が速く、ラムダ式やLINQを使った場合は処理が遅くなっています。

ちなみにラムダ式の記述の部分でCompareToメソッドを使っています。CompareToメソッドはこのメソッドを呼び出すオブジェクトと引数に指定したオブジェクトを比較します。

メソッドを呼び出すオブジェクトの方が、小さいもしくは順番が前の場合にマイナスの値、同じ場合に0(ゼロ)、大きいもしくは順番が後ろの場合にプラスの値を返します。

文字列、日付時刻のソート

C#では要素が数値以外の文字列やDateTime型であってもソートすることができます。

文字列要素のソート

要素が文字列の場合のソートについて、サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、Array.Sortメソッド、List.Sortメソッド、ラムダ式、LINQそれぞれを使って文字列要素を昇順で並び変えています。

日付時刻要素のソート

要素がDateTime型の場合のソートについて、サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、Array.Sortメソッド、List.Sortメソッド、ラムダ式、LINQそれぞれを使ってDateTime型の要素を昇順で並び変えています。

Comparisonデリゲートでカスタムソート

List.Sortメソッドの引数に並び替えの条件を定義したメソッドを表すComparison<T>デリゲートを指定することで、定義した条件によって並び替えることができます。

複数のキーで並び替えを行いたい場合に、キーの指定と並び替えの条件を定義できるので便利です。Comparison<T>デリゲートは以下のように定義されています。

引数xには比較する最初のオブジェクトを指定します。引数yには比較する2番目のオブジェクトを指定します。xがyより小さい値の場合マイナスの値を、等しい場合にゼロ(0)を、大きい値の場合にプラスの値を返します。

ちなみに、デリゲートとは委譲という意味で、関数ポインタのようにメソッドへの参照を使って参照先のメソッドを呼び出すことができます。サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、Comparisonデリゲートを使ってList.Sortメソッドの並び替えの条件を指定しています。まず、2つのメンバ変数を持つInfoクラスを定義しています。

また、CompareメソッドでInfoクラスのメンバ変数ageが昇順に並び替えられるように定義しています。

Compareメソッドを引数に指定したComparisonオブジェクトcを作成し、List.Sortメソッドの引数に指定することで、list内のInfo型の要素を並び替えています。

Compare、CompareToを使用する場合

先ほどはComparisonデリゲートを使って複数キーでもソートを定義できることをお伝えしました。

Comparisonデリゲートを使わずに、クラス内でソートを定義する方法もあります。その場合、IComparerインターフェースやIComparableインターフェースを実装する必要があります。

IComparerインターフェースを実装したクラスではCompareメソッドを実装することでソートを定義します。IComparableインターフェースを実装したクラスではCompareToメソッドを実装することでソートを定義します。

CompareToでカスタムソート

IComparableインターフェースを実装したクラスでCompareToメソッドを定義します。CompareToメソッドはobject型の引数を1つ指定する必要があります。

この引数からメンバ変数を呼び出し、IComparableインターフェースを実装したクラスのメンバ変数と比較して並び替えの順番をきめます。

IComparableインターフェースのCompareToメソッドもstringクラスなどのCompareToメソッドと同じように、マイナスの値か0(ゼロ)もしくはプラスの値を返します。サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、IComparableインターフェースを実装したInfoクラスを定義しています。Infoクラス内ではCompareToメソッドを実装し、引数のオブジェクトのメンバ変数nameとInfoクラスのメンバ変数nameとを比較するように定義しています。

Infoクラスの配列srcをArray.Sortメソッドの引数に指定することで、ソートが実行されています。

Compareでカスタムソート

Comparerインターフェースを実装したクラスでCompareメソッドを定義します。Compareメソッドはobject型の引数を2つ指定する必要があります。

この2つの引数からそれぞれメンバ変数を呼び出し、比較して並び替えの順番を決めます。ComparerインターフェースのCompareメソッドもstringクラスなどのCompareToメソッドと同じように、マイナスの値か0(ゼロ)もしくはプラスの値を返します。

サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、IComparerインターフェースを実装したMyClassクラスを定義しています。MyClassクラス内ではCompareメソッドを実装し、引数のそれぞれのオブジェクトのメンバ変数nameを比較するように定義しています。

Infoクラスの配列srcとMyClassクラスのインスタンスをArray.Sortメソッドの引数に指定することで、ソートが実行されています。

IComparerインターフェースのCompareメソッドの場合2つの引数を指定できるので、Infoクラスとは別のクラスで定義することができます。

定義を後で変更することが予想される場合は、このようにソートを定義するメソッドを別のクラスで定義するようにしておいた方が変更するのが楽になります。

まとめ

ここでは、配列やList型のオブジェクトのソートについて説明しました。

ソートする方法として、Array.Sortメソッド、List.Sortメソッド、ラムダ式、LINQを使う方法などいくつかの方法がありました。それぞれ使い方が異なりますので、目的に合わせて使い分けるようにしましょう。

また、カスタマイズして複数キーでソートする方法についてもいくつかご紹介しました。使いこなすことができるように、この記事を何度も参考にして下さいね!

未来に繋がるプログラミング学習、できていますか?

エンジニアと一口にいっても、フロントエンド、サーバーサイド、アプリ開発、AI関連など様々な業界や職種があり、業務内容や働き方、年収は変わります。

どんな働き方をしたいのか、どのくらい年収が欲しいのかなど具体的なキャリアパスを考えて、それを達成できる学習カリキュラムを考えていかないと、希望する方向性とは違うエンジニアになってしまったり、遠回りの学習に時間を費やしてしまう可能性があります。

侍エンジニア塾では目的から逆算する形で、まずあなたの目指すキャリアをヒアリングさせて頂いてからそれを達成するためのオリジナルの学習カリキュラムを作成しています。

今学んでいることが理想のエンジニアになるために繋がっているか不安でしたら、下記の無料体験レッスン予約カレンダーよりお気軽にご相談ください。

LINEで送る
Pocket

書いた人

長野 透

長野 透

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
[email protected]

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説