TDictionaryをフィルタリング&ソートする

ども、Norimakiです。

久しぶりにDelphiのお話です。

Delphiでデータを扱う際にTDictionaryとかTListなどをよく使います。
で、TDictionaryは検索が効率的だということで、そっちを使いたいんですが、
ソートが出来ないという問題にぶち当たります。

そもそもTDictionaryはソートするもんじゃないぜ。

と言われそうですが、それでもソートしたい時ってのがあるわけで。

じゃあどうするか?

データをTDictionaryに持たせて、順番をTListに持たせる。

という方法でどうだと。

「順番をTListに持たせる」というのは何か気持ち悪い表現ですが、
それはおいておいて、まず、TDictionayのキーをTListに保存するわけですね。
for-in-doを使ってキーを抜き出してTListに保存します。

ここで、必要に応じてフィルタリングをするのも良いでしょう。

で、TListはソートできますから、ソートの際にはTListのソートをつかうと。

TDictionayのキーはどういう型であれ一意ですから、
TListとTDictionaryは1対1で対応しています。

ということで、サンプルがこちら。

こんな感じで。

usesに、Generics.Collections,Generics.Defaults,MMSystem
を追加して下さい。

フォームには、

・SpinEdit2
・SpinEdit3
・StatusBar1
・Memo2

コンポーネントを設置して下さい。
StatusBar1のSimplePanelプロパティはTrueに設定。

SpinEdit2にダミーデータの個数。
SpinEdit3にフィルタリングの数。

を設定します。

フィルタリングについては、
ダミーデータとしてランダムに0から99までの数字が設定され、
設定数以下の数字を抽出する。という仕組みになっています。

面倒なら、ソース中の

LoopCnt :=SpinEdit2.Value;
JudgeCnt:=SpinEdit3.Value;

に適当な数字を入れて下さい。

テスト的には、
LoopCntに1000000、JudgeCntに50をいれてみるといいのではないかと。

うちの環境では、上記設定で

ダミーデータ作成 282 msec
フィルタリング 128 msec
ソート 2,893 msec
表示データ作成 169 msec
表示データ転送 1,965 msec

という感じになりました(詳しい環境状況はよくわかりません)。

あとは、ジェネリクスを使ったり、ソート・フィルタリング部を
分離したりして一般化して使いやすくするとどうかなと。

これが使えるかどうか、意味があるかどうかはわかりませんが、
こういうやり方もありかなと。

ではでは。
Norimakiでした。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする