連載:VB 6ユーザーのための
|
|
|
■コードの記述 〜 並べ替えの実行(SortとReverseを使って)
まず、SortメソッドとReverseメソッドを使う方法から。これはいちばん単純な方法で、学習のコストやコーディングの手間はほとんどゼロ。保守性もいい。ただし、拡張性には欠ける。処理速度についてはやってみないと分からない。ともあれ、コードを見てみよう。
|
||||||||||||||||||
昇順に並べ替えた後、逆順にするコード | ||||||||||||||||||
|
これは極めて単純。キー配列まで逆順にする必要はないのだが、ほかの方法と比較するために両方を逆順にしてある。
■コードの記述 〜 並べ替えの実行(IComparerインターフェイスを使って)
では、次にIComparerインターフェイスを使う方法。インターフェイスというのは「クラスと同じようにプロパティやメソッド、イベントの定義はされているが、クラスと異なり、実装(実際にどういう動きをするか)は決められていないもの」とでもいった感じのものである。
従って、インターフェイスを利用するときには、Implementsステートメントを使って、プロパティやメソッド、イベントを実装したクラスを作る必要がある。
|
||||||||||||||||||
IComparerインターフェイスを使って降順に並べ替えるコード | ||||||||||||||||||
|
IComparerインターフェイスのCompareメソッドには決められた方法はないが、メソッドにパラメータとして渡されるxとyの大小関係によって以下のような値を返すものと定義されている
(1) x < y の場合 → 0より小さい値
(2) x = y の場合 → 0
(3) x > y の場合 → 0より大きい値
従って、降順にしたければ、これとは逆の値を返すようにすればよい。 以降でそのコードを記述している。
それにしても、複雑だ。できるだけ、「日本語」で解きほぐしてみると、次のようになるだろう。
-
のArrayクラスのSortメソッドでは並べ替えの順序が指定できる。そのとき、大小比較に使われるIComparerインターフェイスの実装を指定する必要がある。
-
ではIComparerインターフェイスを実装したクラスの名前を「RevCompare」としておき(実装は後回しにするとして)、「myCompare」という名前で新しいオブジェクトを作成する。これが
で指定されたものだ。
- さて、IComparerインターフェイスを実装しないといけないわけだが、クラス名はRevCompareにしようと
で決めていたので、
では「Public Class RevCompare」と書く。
- このRevCompareというクラスはIComparerインターフェイスを実装するものなので、
ではImplements IComparerと入力する。
- この時点で、
の1行は自動的に入力される(よかった。この長いコードをタイプしなくても済む!)。つまり、Compareメソッドを実装すればよいというわけだ。
- のように、単純に、既定の大小関係とは逆の結果を返すようにすれば降順になるじゃないか。
私自身、.NET Frameworkクラス・ライブラリのリファレンスを何度も読み返して、ようやくおぼろげながらに分かってきたというぐらいの複雑さだが、確かにこの方法だと、並べ替えの順序を自由にカスタマイズできる。が、学習のコストやコーディングの手間はかなりかかる。保守性や拡張性は非常にいい。速度は後のお楽しみとしよう。
なお、このコードを記述すると、Form.vbファイル内に複数のクラス定義が記述されることになる。フォームのクラス定義がファイルの先頭にないとデザイナ・ウィンドウにフォームが表示されなくなるので、RevCompareクラスの定義はファイルの最後に入力するようにしよう。
■コードの記述 〜 並べ替えの実行(DataGridViewコントロールを使って)
最後は、DataGridViewコントロールを使う方法。これは簡単だ。さっきまでの「苦行」がウソのよう。さっそくコードを見てみよう。
|
|||
DataGridViewコントロールを使って並べ替えるコード | |||
|
DataGridViewのSortメソッドには、最初のパラメータにキーとなる列を指定し、2番目のパラメータには並べ替えの方向を指定する。行は長いが、IntelliSenseによって表示されるリストから選択するだけでいいので、入力は簡単だ。学習のコストはさほどかからないし、コードも簡単。保守性もいいが、拡張性もそこそこよさそうだ。
■実行結果と処理時間
実行例の画面は図6のような感じになる。
図6 プログラムの実行例 |
ラジオ・ボタンで並べ替えの方法を選択し、[並べ替え]ボタンをクリックすると、処理にかかった時間が右上に表示される。単位はTick(100ナノ秒)。 |
DateTimeクラスのTicksプロパティは、日時を西暦1年1月1日0時0分0秒からの経過時間を100ナノ秒単位で表しているので、並べ替えにかかった時間は、開始時と終了時の差が200288なら約20ミリ秒となる。
手元の環境(Pentium III 750MHz、メモリ256Mbytes)で3回実行してみて平均を取ってみると、以下のようになった。
|
||||||||
並べ替えにかかる時間の計測結果 | ||||||||
このプログラムではリアルタイム・タイマーを使っているわけではないので、100ミリ秒以下の単位はあまり当てにならないが、かなりの差があることが分かる。ちなみにCore 2 Duo、メモリ2Gbytesの環境でも傾向は同じだった。
このことからも、オブジェクトの作成や利用にはかなりのオーバーヘッドがかかることが分かる。つまり、大量のデータを取り扱うときは繰り返しの回数が多少増えてもシンプルな方法が良さそうだ(べき乗のオーダーで繰り返しが増える場合は話が別だが)。
とはいえ、保守性や拡張性などの要素を無視していいというわけでもない。もっとも、実際に1万件のデータをメモリ上に展開して処理することはそうそうないかもしれないし、数百件程度のデータであれば体感速度にほとんど差は感じられないだろうから、データ量がさほど多くない場合は、状況に合わせて、学習コストや保守性、拡張性に重きを置いた方がいいだろう。
なお、DataGridViewコントロールを使う方法は簡単で分かりやすいのだが、データを準備するのにとんでもなく時間がかかる。上の結果は並べ替えにかかった時間だけを測ったものなので400ミリ秒程度の速さとなっているが、データが準備できるまでに40秒近くかかった。DataGridViewコントロールで大量のデータを扱うのも現実的でない場合があることに注意しよう。
結び − 時には基本を見直すのもいいことだ
今回は、配列の新しい機能を確認することから始めて、ずいぶんとヘンな方向に話がそれてしまった。
.NET Frameworkクラス・ライブラリの「クラス」だけでもVB 6プログラマーには拒絶反応を起こして卒倒してしまう人が、私も含めずいぶんと多いと思うが(でも、数回の連載でだいぶ免疫はついてきたでしょ)、インターフェイスなるものまで登場してしまった。どこかで、「手続き・関数脳」を「オブジェクト指向脳」に切り替える必要があるのだろう。便利な新機能だけでなく、基本の理解も深めていきたいので、近いうちに「クラス」を正面から取り上げてみたいと思う。
INDEX | ||
連載:VB 6ユーザーのためのこれならマスターできるVB 2005超入門 | ||
第6回 配列ってこんなに便利だったの!? | ||
1.サンプル・プログラム7 − ランダムな並べ替えのためのコード | ||
2.サンプル・プログラム8 − 降順に並べ替えるいくつかの方法 | ||
3.並べ替えを行う3つの方法を実装 | ||
「これならマスターできるVB 2005超入門」 |
- 第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用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|
- - PR -