配列名に数字の接尾辞を持つTCLの配列を繰り返す

配列名に数字の接尾辞を持つTCLの配列を繰り返す

TCLには、名前に数字のサフィックス(つまり、名前が数字で終わる)を含む配列があります。

array set ps0 [ list 0 15.885 1 55.43 1 0.254 2 0.227 3 0.177 ]
array set ps1 [ list 0  6.585 1 56.43 1 0.254 2 0.227 3 0.177 ] 
array set ps2 [ list 0 32.485 1 43.13 1 0.254 2 0.227 3 0.177 ] 

TCLではこれを繰り返して値を取得する必要がありますが、数値サフィックスをエスケープするために何をしても配列と内容の両方を取得できません。たとえば、私が試したことはすべて:

ps$i($i)
"ps$i($i)"

あるいは、同様のコレクションを使用することもできます。

set p ps$i

...数値インデックスを持つ配列を取得できません。エラーが発生します。

Original error: can't read "ps": no such variable

...可能なすべての組み合わせ。 TCLでこれをどのように実行できますか?

答え1

実行時に変数名を生成しようとするたびに、これは間違っているという大きな信号なので、使用する必要があります。dictその逆です(通常は配列より使いやすいです)。この場合、多次元辞書は次のようになります。

dict set ps 0 [dict create 0 15.885 1 55.43 1 0.254 2 0.227 3 0.177]
dict set ps 1 [dict create 0 6.585 1 56.43 1 0.254 2 0.227 3 0.177]
dict set ps 2 [dict create 0 32.485 1 43.13 1 0.254 2 0.227 3 0.177]

puts [dict get $ps 1 0] ;# 6.585
dict set ps 1 0 3.14159 ;# Change it to pi

# Print out all the key-value pairs in the ps dict associated with 0
dict for {k v} [dict get $ps 0] {
    puts "$k\t$v"
}

これ文書変数置換の場合$name(index):

名前配列変数の名前を指定し、索引この配列の要素名を提供します。名前文字、数字、下線、および名前空間区切り文字のみを含めることができ、空の文字列にすることができます。文字と数字は標準ASCII文字です(0~9AZそしてアズ)

これがまさにそのようなことがうまくいかない理由の1つです。ps$i($i)名前の変数置換は行われません。この例では、i名前が何である配列変数を探しています。

答え2

dictsは明らかに良い選択です。

配列を使用してこれを行う方法があります。使用upvar動的名前を「一時」名に関連付ける

foreach i {0 1 2} {
    puts "ps$i"
    upvar 0 ps$i tmp
    parray tmp
}
ps0
tmp(0) = 15.885
tmp(1) = 0.254
tmp(2) = 0.227
tmp(3) = 0.177
ps1
tmp(0) = 6.585
tmp(1) = 0.254
tmp(2) = 0.227
tmp(3) = 0.177
ps2
tmp(0) = 32.485
tmp(1) = 0.254
tmp(2) = 0.227
tmp(3) = 0.177

配列キーが連続した整数なのに、なぜ通常のリストを使用しないのか疑問に思います。

関連情報