第12話 グループ化と切り替え

--------------------- 第12話 グループ化と切り替え --------------------------

はじまり、はじまり~。

<さて、ヨタ話は、サッサと省いて、核心を説明してもらいましょうか?>
アンタとの話が全てヨタ話のような気が、もとい! お話しましょう。

問題なのは、グループ化をどう管理するか?であるが当初多量の配列と変数で
行ってみたが、混乱した。コードの割には進まない。切り替えにも手間がかかる。

<切り替え?>
そう、そのファイルがどのグループに属するのか、また単独なのかの判断だ。

<そうよねぇ~。確かに面倒だわ。グループ配列と属性配列が必要ね。>
<ってか、これ両方ないじゃん。一体どーなってるの?>
そこで、登場するのが連想配列の両面利用だ。左辺が属性配列で右辺がグループ配列。

<ああ。例のブラックボックスね。とてもそうは見えないけど>
実際区別は無いからね。そうゆう意味を持たせているだけだから。

<デモデモ、2つの配列がゴッソリ消えるわけでしょ?凄いじゃん>
元々配列はデータの非難場所なので少ないに越したことはないよ。

h["file.pdf"] = "file.pdf" はfile.pdfと言うグループ名(属性)でfile.pdfが
メンバー つまり単独のファイル名となる。

グループの場合は、h[GG5.pdf] = "GG5678.pdf" "GG5987.pdf" などとなる
<コレ、どっかで見たような・・ん?コレって最初に答えた時のだ>
ようやく気がついたね。

<う、嘘でしょう?たった一日でココまで完成してるなんて・・・>
<そう言えばその後の発言「カルチャーショック」が・・・、目眩がして来たわ。>

<確かに「氷付けにして破壊するぐらいの威力は十分」だわ!>
<なんて奴なの!>
こうゆう奴です。 さすがに、あの時点でこうゆう長い説明はちょっとね。

話をも戻すと、文字列を比較して共通文字列があるならグループ名として渡し、
そうでないないなら、ファイル名として渡す。(内容は同じ)

<ソレで、ど~してグループ化されるの?>
グループ名が同じなら、連想配列の特性で、同じ名前の配列が呼び出される。
ソコへ実際のファイル名を追加していくだけだ。

<ナルホロっ。ファイル名を直接、添え字として使うのかぁ。>
<そっかー、だから h[base] = h[base] + GETDIR_FILES[i] + " " だけで済むのね>
後は、その切り替え(グループ名にする。チェックしてファイル名に戻す)がif文だ。

<はぁ。ソレもそれぞれ1行だもんね。もうヤンなっちゃう>
<って事は何? このスクリプトは1行野郎の集合体なの?まさにLiners!!>
それに最終出力で連想配列の内容をそのまま出力すればいい。

<そうよね。グループ化って個別に配列を用意しなくってもコレで十分よね。しっ、知ってたわよ!>
<ダメ押しね。コレも実質1行だもんね。コレ実際の話よねぇ。>
<でも、最初のファイル名は? !ああ、1行3役で定義済みか。効いてるわね>

<トリッキー編とはよく言ったものね。 Linersらしさ爆発じゃないの?>
<でも実際の掲示板の質問で、こうして改めて眺めてみると、1行1行を大切にしているのが良く分かる>

<それにしてもコノ処理内容でif文が全部でたったの3つよ!全部? ・・・全部お話してくれたぁ♪>
<ようやく分かったわ。お姉さま達が好きな理由が、口と外観は悪いけど・・・>
オイッ!!


----------------------------------------------------------------------

提供は: また変な奴に好かれても、と思うLinesでした。

----------------------------------------------------------------------

dir = "C:Documents and SettingsLinersデスクトップtest" // ディレクトリ
Ws = CREATEOLEOBJ("WScript.Shell")
Ws.CurrentDirectory = dir  // カレント変更 concatPDFの為
hashtbl h
base = GETDIR_FILES[resize(GETDIR_FILES, getdir(dir ,"*.pdf")) * 0]

for i = 0 to length(GETDIR_FILES) -2
  str = match(base, GETDIR_FILES[i + 1])
  if str <> "" and base = GETDIR_FILES[i] then base = str + ".pdf"
  h[base] = h[base] + GETDIR_FILES[i] + " "
  if str = "" or (base <> GETDIR_FILES[i] and base <> str + ".pdf") then base = GETDIR_FILES[i + 1]
next

for i = 0 to length(h) -1
  doscmd("<#dbl>C:Program FilesConcatPDFconcatPDF.exe<#dbl> /outfile " + h[i, HASH_KEY] + " " + h[i, HASH_VAL])
next

function match(s1, s2)
  if pos(s1, s2) = 1 or s1 ="" then result = s1 else result = match(copy(s1, 1, length(s1)-1), s2)
fend


----------------------------------------------------------------------
 おまけ
----------------------------------------------------------------------

残念ながら私もココへたどり着くまでに多少はてこずっている。(1日程度だが)
ソコまでの途中経過。(最終実装の前まで)
コレでも連想配列など相当スリム化しているが、やはりグループ化に苦しんでいた。

<な~る。再帰、影番兵、両面利用が未実装か?>
一応、両面利用しているが、グループ化との切り替えがうまくいっていない。

<ここから、実際の.pdf操作に切り替えても、半減させるとは・・・>
データ構造の見直しと工夫の良い例かもね。


----------------------------------------------------------------------

dim s[] = "AA1122.pdf", "AA1145.pdf", "AA1155.pdf", "GG5678.pdf", "GG5987.pdf", "ZZ5678.pdf"
hashtbl h
n = 0
l = length(s)
base = s[n]

while n < l -1
    str = match(base, s[n + 1])
    ifb str <> ""
        base = str + ".pdf"
        if h[base, HASH_EXISTS] = false then h[base] = "<#dbl>" + s[n] + "<#dbl> "
        h[base] = h[base] + "<#dbl>" + s[n + 1] + "<#dbl> "
    else
        ifb base <> s[n]
            n = n + 1
            base =  s[n]
            continue
        endif
        h[s[n]] ="<#dbl>" + s[n] + "<#dbl> "
        base =  s[n + 1]
    endif
    n = n + 1
wend
if str = "" then h[s[n]] ="<#dbl>" + s[n] + "<#dbl> "

// 表示

for i = 0 to length(h) -1
    print h[i, HASH_KEY] + " = " + h[i, HASH_VAL]
next
sleep(30)

// 関数

function match(s1, s2)
    for i = length(s1) to 1 step -1
        result = copy(s1, 1, i)
        if pos(result, s2) = 1 then exit
    next
    result = ""
fend