この特定の問題は、再帰的に処理するのが最適です。特に、特定のカウンタのカウントを生成すると、チェーン内の次のカウンタを処理するためにコールバックが行われます。結果を正しい順序でまとめるには少し注意が必要です(いくつかの方法があります)が、リストのリストとしてデータを生成し、それをさらに処理したり、あなたが選ぶように印刷されます。
再帰を開始するためにデフォルトの引数を使用することに注意してください。ラッパープロシージャーを使用することなく、これを実行することは可能ですが、それは洗練されたものです。
proc genseq {definition {current {}}} {
# Get the next part of the definition
lassign [lindex $definition 0] columns prefix limit
set definition [lrange $definition 1 end]
set result {}
for {set i 0} {$i < $limit} {} {
# Handle the appending of bits relating to the counter at the current level
set cur $current
foreach c $columns {
lappend cur "$prefix$i"
incr i
}
# If we have more definition to process, recursive call. Otherwise just accumulate
if {[llength $definition] > 0} {
lappend result {*}[genseq $definition $cur]
} else {
lappend result $cur
}
}
return $result
}
のは、それをテストしてみましょう:
set seqinfo {
{{XD} PD 2}
{{XB} PB 4}
{{XA0 XA1} PA 4}
}
# A bit of trickery to get approximately the right output format
puts \{\{[join [genseq $seqinfo] "\}\n\{"]\}\}
は、この出力を生成します。
{{PD0 PB0 PA0 PA1}
{PD0 PB0 PA2 PA3}
{PD0 PB1 PA0 PA1}
{PD0 PB1 PA2 PA3}
{PD0 PB2 PA0 PA1}
{PD0 PB2 PA2 PA3}
{PD0 PB3 PA0 PA1}
{PD0 PB3 PA2 PA3}
{PD1 PB0 PA0 PA1}
{PD1 PB0 PA2 PA3}
{PD1 PB1 PA0 PA1}
{PD1 PB1 PA2 PA3}
{PD1 PB2 PA0 PA1}
{PD1 PB2 PA2 PA3}
{PD1 PB3 PA0 PA1}
{PD1 PB3 PA2 PA3}}
練習としてヘッダーと余分なスペース行を入れておきます。 (また、Tclはリストをコンマで区切っていません;実際にカンマは普通の文字で、式の外では特別なものではありません。)
何を試しましたか? XA1を別のマッピングエントリとして設定すると、あなたの人生が楽になります。 –
これは、単一のシーケンスカウンタからの値が複数の列で使用される方法のため、正確ではありません。 –