Tcl8.5からの新しいデータ型のdictについて。~
~
リストと配列の中間みたいな。構造体みたいに扱うリストの要素に名前でアクセスできなかったり、配列をprocから返せなかったり、そういう不便なところを解消するのが使いどころな気がする。配列より速いらしいが、Tclの場合リストもデータによっては配列より速い場合もあるので、list,array,dictの三つで比較してみないとなんともわからん。
リストと配列の中間みたいな。構造体みたいに扱うリストの要素に名前でアクセスできなかったり、配列をprocから返せなかったり、そういう不便なところを解消するのが使いどころな気がする。%%keyとvalueのペアで構成された、ただのリストに見える・・・%%Hashで実装されてた。配列より速いらしいが、Tclの場合リストもデータによっては配列より速い場合もあるので、list,array,dictの三つで比較してみないとなんともわからん。とりあえずはまだ8.5に移行したくないので、8.4用のライブラリをインストールして使ってみた。

***基本的な使い方 [#uf51e472]
***コマンド早引き [#ddbf8502]
,''dict append'' '''varName key ?value ...?'''          ,keyの値の末尾にvalueを連結。
,''dict create'' '''?key value ...?'''                  ,dictの作成。
,''dict exists'' '''%%%dictionary%%% key ?key ...?'''   ,keyが存在するかどうか。
,''dict filter'' '''%%%dictionary%%% filterType ...'''  ,フィルターをかけて要素を間引いて返す。
,''dict for'' '''{keyVar valueVar} %%%dictionary%%% script''',foreachみたいな。
,''dict get'' '''%%%dictionary%%% ?key key ...?'''  ,keyの値を返す。
,''dict incr'' '''varName key ?increment?'''       ,keyの値を増やす。incrと同じ。
,''dict info'' '''%%%dictionary%%%'''              ,dictの内部情報を返す。
,''dict keys'' '''%%%dictionary%%% ?pattern?'''    ,keyのリストを返す。
,''dict lappend'' '''varName key ?value ...?'''    ,keyの値をリストとして要素を追加。
,''dict merge'' '''?%%%dictionary%%% ...?'''       ,複数のdictを合成して返す。
,''dict remove'' '''%%%dictionary%%% ?key ...?'''  ,keyのペアを削除したdictを返す。
,''dict replace'' '''%%%dictionary%%% ?key value ...?''' ,keyをvalueで置換えたのを返す。
,''dict set'' '''varName key ?key ...? value'''          ,keyにvalueをセット。
,''dict size'' '''%%%dictionary%%%'''                    ,要素数を返す。
,''dict update'' '''varName key varName ?key varName ...? script''',keyをvarNameにアサインしてコードを実行(8.5専用?)
,''dict unset'' '''varName key ?key ...?'''              ,keyのペアを削除。
,''dict values'' '''%%%dictionary%%% ?pattern?'''        ,値のリストを返す。
,''dict with'' '''varName ?key ...? script''',dictの名前空間でコードを実行(8.5専用?)
-varNameはdict変数の名前で、%%%dictionary%%%は値そのものなので注意。lappend, append, set, unset, incr以外は値。tclのコマンドと同じか。
-get, exists, set, unsetでkeyを複数指定するのはネストされたdictへのアクセス。
-8.5専用と書いてるのは8.4用ライブラリには(まだ?)コマンドが無いもの。

***基本的な使い方 [#t94be0c2]
 set d [dict create name toyota]
で作成。必要に応じてlist型と相互変換してるので、[list name toyota]でリストを作って入れても、dictコマンドでdict型に変換するので、使う分にはキーと値のペアのlist型とdict型はあまり気にしないでよいみたいだ。~
あとは普通に上の早引きを見ながらちょちょいと使ってみれば大体わかると思う。。。
 set d [dict create]
 dict set d name toyota
 dict set d code 7203
みたいな。

***ネスト [#k85d37b6]
dictはネストできる。イメージとしては構造体のネストみたいな。keyを複数指定できるコマンド群はネストで使う。
dict

***dict filterの練習 [#o7417ebd]
フィルターはkey, value, scriptの三つの種類がある。
 dict filter dict key pattern
 dict filter dict value pattern
 dict filter dict script {keyName valueName} body

 % dict filter {aa 0 ab 1 ac 2 ba 3 bb 4 bc 5} key a*
 ac 2 aa 0 ab 1

 % dict filter {n1 akane n2 aiko n3 ayumi n4 ai} value ai*
 n2 aiko n4 ai

 % dict filter {toyota 1.15 honda 3.05 nissan -0.71} script {k v} {expr $v>0}
 toyota 1.15 honda 3.05

***dict updateの練習 [#sc98224a]
 set info {name toyota code 7203}
 dict update info name nameVar code codeVar {
     set nameVar [string toupper $nameVar]
     set codeVar ($codeVar)
 }
 puts $info

 name TOYOTA code (7203)

と、まあこの場合、infoのnameがnameVarに、codeがcodeVarにアサインされて、ボディ中で色々いじって、最後にinfoに値が書き戻されるという。dict withも似たようなもんだが、dict updateは要素の中身を追加できるとこがdict withと違うようだ。~
~
perを追加してみる例。
 set info {name toyota code 7203 price 5280}
 dict update info per perVar {
     set perVar 15
 }
 puts $info

 name toyota per 15 price 5280 code 7203
あまり良い例じゃないような・・・。まあいいか。~
~
priceを削除してみる例
 set info {name toyota code 7203 price 5280}
 dict update info price priceVar {
     unset priceVar
 }
 puts $info

 name toyota code 7203
最後の書き戻しの時に、マップされた値(この場合priceVar)が無いとdictからその対応したキーが削除される。~
~
body中でもdictにアクセスすることもできる。priceの2倍の値をprice2というキーを新しく作って入れてみる。
 set info {name toyota code 7203 price 5280}
 dict update info price2 price2Var {
     set price2Var [expr 2 * [dict get $info price]]
 }
 puts $info

 price2 10560 name toyota price 5280 code 7203

***dict withの練習 [#r4514666]
BASICのwithみたいなイメージ?
 set info {name toyota code 7203 price 5280}
 dict with info {
     puts name=$name
     puts code=$code
     puts price=$price
 } 
みたいな。書き換えても反映される。~
~
dict updateと同じように、対応した名前が見つからない時は要素が削除される。
 set info {name toyota code 7203 price 5280}
 dict with info {
    unset name
 }
 puts $info

 price 5280 code 7203


***リンク [#x5748fb9]
-http://www.tcl.tk/man/tcl8.5/TclCmd/dict.htm
-http://www.tcl.tk/cgi-bin/tct/tip/111.html
-http://www.tcl.tk/cgi-bin/tct/tip/212.html
-[[dict:http://wiki.tcl.tk/5042]]
-[[Dict VS Array Speed:http://wiki.tcl.tk/13826]]
-http://pascal.scheffers.net/software/ (Tcl8.4用のdictライブラリ)
----
[[CategoryTclTk]]


HTML convert time: 0.003 sec.