Listを使用して2つの集合を効率よく比較する

2008年12月01日 01:28

ある集合 list1 の要素がある別の集合blakklist1 の要素を含むかどうかをチェックするにはどうしているでしょうか。

list1 = {"aa", "bb", "cc", "dd", "ee"}
blacklist1 = {"bb", "cc"}

このような場合以下のようなコードを書くことが多いのではないでしょうか。

Sub Click(Source As Button)
Dim list1(4) As String
Dim blacklist1(1) As String

list1(0) = "aa"
list1(1) = "bb"
list1(2) = "cc"
list1(3) = "dd"
list1(4) = "ee"

blacklist1(0) = "bb"
blacklist1(1) = "cc"

Forall l In list1
Forall b In blacklist1
If (b = l) Then
Print "Hit! " & l
End If
' blacklist1 が重複の無い集合の場合、ここで抜ける事が出来ます
Exit Forall
End Forall
End Forall
End Sub

僕自身、このような処理は上のように書いていました。
別にこの方法で特に問題があるとは思っていなかったのですが、先日以下のTechnoteにあるサンプルを見てなるほど・・・と思ってしまいました。

Sample agent for updating existing folders in a database when they do not exist in the inherited template (#1086404)

ここではフォルダーのアップデートをする際にシステムフォルダだけアップデートをスキップするような処理を加えている訳ですが、上の例に当てはめると、以下のような二つの集合の比較になっている事が分かると思います。

list1: 全ビュー またはフォルダ
blacklist1: ignore_list (テンプレートに含まれているフォルダ名)

同じ処理をしているわけですが、Listを上手に使うことによって、Forallが入れ子構造になることを回避しています。上の例で言うと、blacklist1を配列ではなく、リストとして定義する事によって効率のよい比較を行っているのです。

まず、リストに関してはあまり使ったことが無い方も多いのではないかと思うので、リストとはどういうものかを手短に説明しておきます。Perlを知っている方なら、Perlの連想配列のような概念です、と言えば説明終了なのですが、要するに以下のように配列のインデックスを数字ではなく、文字列にしたものです。

Dim blacklist List As String
blacklist1("bb") = 1

今回は、実はこのリストの値である部分は使用しないので、右辺では1のようなダミーの値をセットしています。
 ここでIsElement関数を使って、その文字列が、blacklistの引数として有効であるか無いかを比較する事によって効率のよい比較を行っているのです。

変更後のコードを見てみて下さい。


Sub Click(Source As Button)
Dim list1(4) As String
Dim blacklist1 List As String

list1(0) = "aa"
list1(1) = "bb"
list1(2) = "cc"
list1(3) = "dd"
list1(4) = "ee"

' 右辺の1に特に意味はありません。
blacklist1("bb") = 1
blacklist1("cc") = 1

Forall l In list1
If Iselement(blacklist1(l)) Then
Print "Hit! " & l
End If
End Forall
End Sub


細かい話はおいておくとして、すっきりしたのが分かるのではないでしょうか。
このような比較は特に、blacklist1のサイズが大きくなればなるほど効率よくなるのではないかと思います。 僕自身、実は LotusScript のリストは、デザイナーヘルプにあるように、

emp_list("山田 太郎") = 123456

のような文字列をキーにしたデータ格納をしたいとき以外には、使用しないのでは?と思っていて、実際には使用したことはなかったのですが、このように二つの集合比較のような処理でも利用出来るとするともっと使えるチャンスはあったのではないかと思って反省しました。

 是非このような処理を使う機会が僕以上にある方は、僕に代わって利用してみて下さい。。。


コメント

    コメントの投稿

    (コメント編集・削除に必要)
    (管理者にだけ表示を許可する)

    トラックバック

    この記事のトラックバックURL
    http://hnagasim.blog8.fc2.com/tb.php/30-73f41f55
    この記事へのトラックバック


    最新記事