T第11話:連想配列とインデックス

--------------------- 第11話 連想配列とインデックス --------------------------


はじまり、はじまり~。


<あのう最近話題が古くないですか?>
まあファイル関連は少ないからね。

<そうじゃなくて、過去の総集編みたいな感じなんだけど>
そうだよ。

<やっぱり新しいのがいい!>
コレが読まれるころには古くなってるさ。

<でもぉ~~~~~>
分ったから。現時点での最新を取り上げよう。え~~っとコレかな?

珍しい!連想配列だ。外部ファイルではないが、ほとんどファイル処理だね。
<どれどれ? これアンタが答えてないジャン!!>
うん♪ 楽でいい。

<ダメジャン!>
そんなことないよ。質問者も満足しているようだし、茶々入れるのヤメトコ!

<お茶入れて♪>
ハイハイ。梅昆布茶がお勧め・・じゃないでしょ!

<やっぱり、ツッコミ所があるわけね?>
このままでは同じキーのデータが上書きされて消えてしまう。

<それはマズイわね。>
しろまささんは、連想配列のお手本を示しているワケだし、キーの重複はお勧めで無いからね。

<何とかならないの?>
連想配列のキーは重複できないので工夫が必要。 ってかどんな配列でも添え字の重複は上書きが当然!

<工夫って?>
自分で考えよう。 シンキング・タイム!

<タイム・アウト!>
速!

<わかんないものはワカンナイ! 考えるだけ無駄無駄! でも重複しなければ良いだけだよね?>
それだ!

連想配列のキーは文字列なので、同じ数字+文字列全体をキーに出来る。
数字をキーにしている当たり、まだ通常配列の感覚が抜け切れていないね。無理も無いが。

また文字列の大小比較なので、数字の場合は一度フォーマットして桁数を揃えて文字列に戻す必要がある。
<何だか長くなりそうね>
そう? コレなんだが。

str = replace(TB_StrALL, chr(10), "")
HashTbl Hash_Data = HASH_SORT

while str <> ""
  t_StrLine = token("<#cr>", str)
  Hash_Data[format(val(BetweenStr(t_StrLine, "<", ">")), 5) + t_StrLine] = t_StrLine
wend

For i = Length(Hash_Data) - 1 to 0 step -1
  Print Hash_Data[i, HASH_VAL]
Next
Sleep(30)

TextBlock TB_StrALL
sdvwjek<4>dfpogdf
df<6>lkjsdf6drt
oiwnfgh<2>dfoit
sdltrdfkjsl<5>ddsf
asdkjfhejk<1>slekj
otoo<2>it
sdkl45kggsd9gpi<3>o
EndTextBlock

<何で機能を追加してるのに短くなってんよ! んっ? あ、あっこ、コレは・・・>
そう,気付いたね。まじめにスクリプト物語を読んでれば、コノくらい当然の結果だね。

<単なる冗談じゃなかったのね。>
あのね~。

<質問者の要求に完璧に答えて置きながら、ループの中身が2行とは、どうゆう事?>
<まじめに読む必要がありそうね「フォーマットして桁数を揃えて文字列に戻す」・・・>

<へっ?? この書き方ワザとだわ!! んっ?? まさか・・・やっぱり!>
<「あらかじめそれぞれのラインをTokenで切り出しつつKeyとなる<>の中の値を解析して、行頭にダミー付加してからやれば」>

<質問者の理解度としろまささんのスクリプトのトレース具合を考慮に入れた上で、最初の答えと、考え方に戻している。>
<それに、説明通りのストレートな書き方、しかも2行・・・こ,こんな事が実際にあるなんて・・・>

<だからスクリプトを読み始めると、いやにスンナリ頭に入ってきて、それで気付いた!>
<ってか気付く事自体も既に計算済みってワケねキット・・・>


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

提供は: 役に立つスクリプト物語。 役立たずのLinersでした。

----------------------------------------------------------------------
     連想配列のSORTについて ぺぐ    
    連想配列という便利そうな概念があるのをサンプルで見つけたのですが
いまひとつ具体的な使い方の例が少なく難儀しています。

今、例として下のような文字列がクリップボード内にあって
--------------------------
sdvwjek<4>dfpogdf
df<6>lkjsdf6drt
oiwnfgh<2>dfoit
sdltrdfkjsl<5>ddsf
asdkjfhejk<1>slekj
otoo<2>it
sdkl45kggsd9gpi<3>o
--------------------------
これを、"<>"で囲まれた部分(同じ値あり)をKeyにして降順Sortをかけて

--------------------------
df<6>lkjsdf6drt
sdltrdfkjsl<5>ddsf
sdvwjek<4>dfpogdf
sdkl45kggsd9gpi<3>o
oiwnfgh<2>dfoit
otoo<2>it
asdkjfhejk<1>slekj
--------------------------
のように並べ替えてクリップボードを書き換えたいのですが、
連想配列を使うと簡単にできるのでしょうか?

あらかじめそれぞれのラインをTokenで切り出しつつ
Keyとなる<>の中の値を解析して、行頭にダミー付加してからやれば
サンプルを例にして Sortできそうなのですが、
それをしなくてもシンプルにできるものなのかが今ひとつわかりません。

ご教示いただける詳しい方いらっしゃいましたら
お願いいたします。
DATE:2010/3/31(Wed) 07:59 No.2949    
   
    RE:連想配列のSORTについて しろまさ    
   
    TextBlock TB_StrALL
sdvwjek<4>dfpogdf
df<6>lkjsdf6drt
oiwnfgh<2>dfoit
sdltrdfkjsl<5>ddsf
asdkjfhejk<1>slekj
otoo<2>it
sdkl45kggsd9gpi<3>o

EndTextBlock


HashTbl Hash_Data  = HASH_SORT
Dim t_Count     = 1
Dim Num_CR_Befor  = 0
Dim Num_CR_After  = Pos("<#CR>", TB_StrALL, t_Count)
Repeat
   Dim t_StrLine  = Trim(Copy(TB_StrALL, Num_CR_Befor, Num_CR_After - Num_CR_Befor))
  Hash_Data[BetweenStr(t_StrLine, "<", ">")]  = t_StrLine
  Num_CR_Befor  = Num_CR_After
  t_Count     = t_Count + 1
  Num_CR_After  = Pos("<#CR>", TB_StrALL, t_Count)
Until  Num_CR_After = 0

Dim i
For i = 0 To Length(Hash_Data) - 1
  Print Hash_Data[i, HASH_VAL]
Next
Sleep(5)
DATE:2010/3/31(Wed) 13:40     WEB
   
    連想配列のSORTについて ぺぐ    
   
    しろまささん ありがとうございます。
なるほど。
KEY部をデータ部を別々に扱えて、なおかつそれぞれをシンクロさせることができるのですか。
連想配列の格納方法と取り出し方法が一種独特ですね。

実は、 HASH_KEYやHASH_VALの使い方がいまひとつわからず
元のデータの行頭にKey部を付加してから全体で扱うスクリプトを
数時間かかってなんとか完成させたのですが
ご紹介いただいた方が文字列操作(事前に付加して終わったらKEYを消す等)の
部分を考えなくてよいですし、その分ケアレスミスの確率が少なくすみそうです。

あと蛇足ですが、文頭の
TextBlock ・・・・  EndTextBlock
って文字列の宣言方法ははじめて知りました!!
(HELPにもちゃんと出てましたね)
これまで、複数ラインを""で区切って<#Cr>でつなげていたので
コーディング上いまひとつ美しくなかったのですが
これでまたひとつスマートなコードが書けそうです。

いろいろと参考になる知識をありがとうございました。
DATE:2010/3/31(Wed) 17:50