.NET TIPS 配列を独自の順序でソート(並べ替え)するには?デジタルアドバンテージ2004/10/08 |
|
|
数値や文字列の配列のソート(並べ替え)は、Arrayクラス(System名前空間)の静的なメソッドであるSortメソッドにより既定の順序でソートできるが、本稿では独自の順序により配列をソートする方法について解説する。
Array.Sortメソッドによる配列のソート
まず、既定の順序によるソートついて簡単に見ておこう。配列の要素が数値型や文字列型をソートする場合には、Array.Sortメソッドのパラメータに、その配列を指定するだけだ。次にそのサンプル・プログラムを示す。
|
|
Array.Sortメソッドにより文字列の配列をソートするC#のサンプル・プログラム(arraysort.cs) | |
|
|
Array.Sortメソッドにより文字列の配列をソートするVB.NETのサンプル・プログラム(arraysort.vb) | |
このようにしてソートできる配列は、その要素のクラスがIComparableインターフェイス(System名前空間)を実装している必要がある。ほとんどの数値型や文字列型(Stringクラス)は、このインターフェイスを実装している(このインターフェイスについては後述)。
独自の比較ルーチンを実装するCompareメソッド
Arrayクラスにおける配列のソートは、配列から取り出した2つの要素について、その大小をそれぞれの要素から得られる比較可能な値(数値の場合にはその値、文字の場合にはその文字コードの値など)により比較し並べ替えるという作業の繰り返しである(正確には、クイックソートと呼ばれるアルゴリズムが用いられている)。独自の順序によるソートというのは、2つの要素を比較してその大小を決定する部分を独自に実装するということにほかならない。
ArrayクラスのSortメソッドでは、このような2つの要素の比較ルーチンを外部から提供できる仕組みを持っている。この仕組みを利用するには、第2パラメータとしてIComparerインターフェイス(System.Collections名前空間)のオブジェクトを指定するSortメソッドを使用する。
Array.Sort(strArray, icompareObject);
IComparerインターフェイスは、次のようなシグネチャを持つCompareメソッドを定義しているインターフェイスである(以下はC#による定義)。
int Compare(object x, object y)
このインターフェイスを実装したクラスのオブジェクトをSortメソッドに渡すことにより、そのクラスのCompareメソッドがSortメソッドの内部で要素の比較時に使用されるという仕組みである。
Compareメソッドは、パラメータにより受け取った2つのオブジェクト(xとy)を比較し、xがyより小さい場合には戻り値として負の値を、等しい場合には0を、そしてxがyより大きい場合には正の値を返すという役割が決められている。
文字列の長さによるソート
ここでは例として、文字列の長さによるソート(文字列の短い順に並べ替える)を考えてみよう。この場合には、Compareメソッドの定義は次のようになる(C#の場合。VB.NETについては後述のサンプル・プログラムを参照)。
public int Compare(object x, object y) {
string str1 = (string)x;
string str2 = (string)y;
return str1.Length - str2.Length;
}
Compareメソッドのパラメータはobject型でなければならないため、比較に先立って、それぞれをキャストして文字列型に戻す必要がある(ここでは割愛しているが、キャストに失敗する場合には例外をスローするのが一般的である)。Lengthプロパティは文字列の長さを得るためのものだ。2つの文字列の長さを引き算することにより、Compareメソッドに期待されている戻り値を得ることができる。
このCompareメソッドを含む、IComparerインターフェイスを実装したクラスを利用して文字列の配列をソートするサンプル・プログラムを次に示す。
|
|
文字列の長さにより配列をソートするC#のサンプル・プログラム(strlensort.cs) | |
|
|
文字列の長さにより配列をソートするVB.NETのサンプル・プログラム(strlensort.vb) | |
もし、文字列の長さの長い順にソートした場合には、最後のreturn文における引き算の順序を入れ替えて「str2.Length - str1.Length」とすればよい。
なお、ここではArrayクラスのSortメソッドについて取り上げたが、可変長の配列として利用できるArrayListクラス(System.Collections名前空間)のSortメソッドもArrayクラスとまったく同じ仕組みを持っており、IComparerオブジェクトにより独自の順序でソートが可能だ。
IComparableインターフェイス
ちなみに、先に示した「Array.Sort(strArray)」によるソートは、実際にはCompareクラス(System.Collections名前空間)クラスのComparerメソッドを比較ルーチンとして利用している(もちろん、このCompareクラスもIComparerインターフェイスを実装している)。つまり、Array.Sortメソッドのデフォルトの比較ルーチンが、CompareクラスのCompareメソッドだということだ。
そしてさらに、このCompareクラスのCompareメソッドでは、比較対象となっているオブジェクトが持つCompareToメソッドを呼び出すことにより、その比較を行う。CompareToメソッドは、IComparableインターフェイスで定義されているメソッドである。パラメータで配列のみを指定したArray.Sortメソッドを利用する場合に、その配列がIComparableインターフェイスを実装している必要があると先に述べたのはこのためである。IComparableインターフェイスとCompareToメソッドについては、「TIPS:自作クラスによる配列をソート(並べ替え)するには?」で解説している。
カテゴリ:クラス・ライブラリ 処理対象:配列 使用ライブラリ:Arrayクラス(System名前空間) 使用ライブラリ:IComparableインターフェイス(System名前空間) 使用ライブラリ:IComparerインターフェイス(System.Collections名前空間) 使用ライブラリ:ArrayListクラス(System.Collections名前空間) 使用ライブラリ:Compareクラス(System.Collections名前空間) 関連TIPS:自作クラスによる配列をソート(並べ替え)するには? |
|
「.NET TIPS」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|