Как использовать puts с несколькими переменными в одном аргументе в Tcl?

#loops #printing #tcl #puts

#циклы #печать #tcl #puts

Вопрос:

У меня есть ряд списков, таких как a1, a2, a3, a4, …. Я хочу напечатать их в цикле, таким образом, и a, и i являются переменными. Как я могу это сделать?

Это не работает.

 for {set i 1}....
 puts $a$i
}
 

Заранее спасибо

Комментарии:

1.Вы имеете в виду, что у вас есть переменные a1 , a2 , a3 , и т.д.?

2. Если да, возможно ли переключиться на использование массива, a(1) , a(2) , a(3) , и т.д.? Это намного проще, чем код для чтения из переменной переменной…

3. Спасибо за ваш ответ, но нет, каждый из них представляет собой отдельные списки, такие как: set a1 [список 1 2 3 4]; set a2 [список 10 20 30 40]; set a3 [список 100 200 300 400]

4. Это не showstopper. Вы можете сделать set a(1) [list 1 2 3 4]; set a(2) [list 10 20 30 40]; # ... . Лучше всего следовать советам @DonalFellows по использованию массива, который, так сказать, представляет собой набор переменных с общим префиксом.

Ответ №1:

В идеале они должны быть в ассоциативном массиве, но в противном случае…

Для чтения из переменной, имя которой не является константой, используйте set команду только с одним аргументом вместо $ синтаксиса. (Это использование set предшествует $ .)

 for {set i 1} {$i <= 3} {incr i} {
    puts [set a$i]
}
 

Однако было бы лучше использовать массив (чтобы переменные эффективно назывались a(1) , a(2) , etc вместо a1 , a2 , etc). Но это означает изменение кода, который также создает переменные.

 for {set i 1} {$i <= 3} {incr i} {
    puts $a($i)
}
 

Другим реалистичным вариантом для доступа к переменным переменным является upvar команда. На самом деле это не рекомендуется в глобальном пространстве имен, но в процедуре это очень эффективно.

 proc printThree {} {
    for {set i 1} {$i <= 3} {incr i} {
        upvar 1 a$i vbl
        puts $vbl
    }
}
 

Это особенно хорошо работает при выполнении более сложных операций, чем просто печать значения.

Комментарии:

1. Спасибо, это именно то, что я хочу. grazie Mille!

Ответ №2:

Как список:

 set a1 [list 1 2 3 4]
set a2 [list 10 20 30 40]
set a3 [list 100 200 300 400]
set a4 [list 1000 2000 3000 4000]

foreach i [list {*}$a1] { puts "$a$i: [set a$i]" }
# $a1: 1 2 3 4
# $a2: 10 20 30 40
# $a3: 100 200 300 400
# $a4: 1000 2000 3000 4000
 

Как массив:

 array set a {
 1 {1 2 3 4}
 2 {10 20 30 40}
 3 {100 200 300 400}
 4 {1000 2000 3000 4000}
}

parray a
# a(1) = 1 2 3 4
# a(2) = 10 20 30 40
# a(3) = 100 200 300 400
# a(4) = 1000 2000 3000 4000
 

Как dict:

 set a [dict create         
a1 {1 2 3 4}               
a2 {10 20 30 40}           
a3 {100 200 300 400}       
a4 {1000 2000 3000 4000}]  

dict for {k v} $a { puts "$k: $v" }
# a1: 1 2 3 4
# a2: 10 20 30 40
# a3: 100 200 300 400
# a4: 1000 2000 3000 4000
 

Как матрица:

 package require struct::matrix 

::struct::matrix xdata
xdata add columns 4
xdata add rows    4

xdata set rect 0 0 {
{1 2 3 4}
{10 20 30 40}
{100 200 300 400}
{1000 2000 3000 4000}
}

join [xdata get rect 0 0 end end] n
# 1 2 3 4
# 10 20 30 40
# 100 200 300 400
# 1000 2000 3000 4000

#cleanup 
xdata destroy