VBAHaskellの紹介 その8 (ソート関連)
ソート関連は別にHaskellぽくない。特徴と言えるのは任意の比較関数が使えることくらいだ。
sortIndex 昇順ソート後のインデックス配列
sortIndex_pred 任意の比較関数によるソート後のインデックス配列permutate (Sub) 配列をソートインデックスを使って実際にソートする
lower_bound ソート済み配列からのキーの検索
lower_bound_pred ソート済み配列からのキーの検索
upper_bound ソート済み配列からのキーの検索
upper_bound_pred ソート済み配列からのキーの検索
equal_range ソート済み配列からのキーの検索
equal_range_pred ソート済み配列からのキーの検索
個々の機能は分かると思うので、多少注意を要する点だけあげる。
1. sortIndexとsortIndex_predは対象配列を直接ソートするわけではなく、下図の赤文字部分にあたるソート後のインデックスを出力する。*1 sortIndexは昇順ソートであり、降順指定はない。*2
対象配列 : 3 , 1, 5 , 2 -> 1 , 2 , 3 , 5
インデックス : [0 1 2 3] -> [ 1 3 0 2 ]
2. ソートした結果の配列を得たいときには、subM関数 *3 を使う。
' 配列を m をソートしたい
index = sortIndex(m) ' または index = sortIndex_pred(m, comp)result = subM(m, index) ' 昇順
result = subM(m, reverse(index)) ' 降順
3. 対象配列は1次元か2次元のみであり、自動的に判別される。2次元の場合は行をレコードと見たソートであり、列方向のソートはできない。ソートキーはsortIndex関数の第2引数に指定することが可能で、優先したい順に列番号を並べる。省略した場合には全列がキーとなる(左にあるほうの列が優先)。
' 2次元配列 m の0列目, 2列目, 4列目 をソートキーにする
sortIndex(m, Array(0, 2, 4))
4. sortIndex_pred では2引数の比較関数を与えることによって自由な順序でソートできる。この比較は「第1引数が第2引数より小さい」とき1を、そうでないとき0を返すものとする。比較関数さえ書ければいいので、型がバラバラでもジャグ配列でもソートできる。test_module にそのようなテスト関数を追加した。(Function comp000とSub sortTest)
「比較関数を書けばその通りにソートできて当然ではないか」というのが通常の感覚だと思うが、VBAではなかなかできなかった。
2次元配列を対象とする場合は1行を一つの配列とみて比較関数を書く。
5. upper_bound と upper_bound_pred の返り値、そしてequal_range と equal_range_pred の返り値の2番目の要素は検索範囲の最後の要素の「次の」インデックスである。C++の<algorithm>にあるのと同じだ。
6. 残念ながらAPIのC++プログラムにコンパイル時処理はない。
VBAHaskellの紹介 その7 (bind1stとbind2nd)
http://mmyymmdd.hatenablog.com/entry/2015/04/16/224313