在Tcl中动态创建数组

Zuc*_*erg 1 traversal tcl multidimensional-array

我试图动态填充数组,而不是通过运行如下所示的计数器手动设置它:

set all_list  { <my list>}
set num_pc_a_b 10

for {set i 0 ;set j 0 ; set k 0} {$j < $num_pc_a_b} {incr j; incr i ;incr k} {
    array set link_map  {[lindex $all_list $i] $j $k 0 }
}
Run Code Online (Sandbox Code Playgroud)

并希望访问如下变量:

foreach {key value value1 value2} [array get link_map] {
    puts "key is $key"
    puts "value is $value"
    puts "value is $value1"
    puts "value is $value2"
}
Run Code Online (Sandbox Code Playgroud)

但它不起作用.我在这里做错了吗?

kos*_*tix 5

对我来说,你真正想做的事情并不是很明显,所以我会做出一些猜测.

在任何一种情况下,请注意您的使用array set ...似乎是错误的:此命令采用数组的名称和它解释为交替键和值的列表,在该数组中为映射到该键后面的值的每个键创建一个条目.您似乎只想在每次迭代时将特定键设置为特定值 - 这是通过set array(key) value语法完成的.

另请注意,在您的示例中j,ik变量似乎在每次迭代时具有相同的值.据说它只是现实世界代码中的遗留物,但是否则只有一个变量就足够了.

猜一:你想将每个键映射到值列表.这不会像在您的示例中那样工作,因为在Tcl中,数组将每个键映射到一个值; 这个值可能是一个列表.如果我的猜测是正确的,那么走的路是:

for {set i 0 ;set j 0 ; set k 0} {$j < $num_pc_a_b} {incr j; incr i ;incr k} {
    set link_map([lindex $all_list $i]) [list $j $k 0]
}
foreach {key val} [array get link_map] {
    foreach {v1 v2 v3} $val break ;# see a note below
    puts "key is $key"
    puts "value is $v1"
    puts "value is $v2"
    puts "value is $v3"
}
Run Code Online (Sandbox Code Playgroud)

猜猜两:根据你foreach对显示的使用情况来判断,你可能根本不想使用数组,而是列表:

set links [list]
for {set i 0 ;set j 0 ; set k 0} {$j < $num_pc_a_b} {incr j; incr i ;incr k} {
    lappend links [lindex $all_list $i] $j $k 0
}
foreach {key v1 v2 v3} $links {
    puts "key is $key"
    puts "value is $v1"
    puts "value is $v2"
    puts "value is $v3"
}
Run Code Online (Sandbox Code Playgroud)

你也可以不是一个平面列表,而是一个改变键和值的列表,每个值都是[list $j $k 0]第一个猜测示例中的值.

更新

猜猜三.你把我们的问题标记为multidimensional-array.我在你的片段中没有看到任何多维度的痕迹,但如果你真的想要它,Tcl中通常的范例就是使用复合键.例如,如果要按值的值键入数组j,i并且k每次迭代都有这些变量,请使用以下内容:

for {set i 0 ;set j 0 ; set k 0} {$j < $num_pc_a_b} {incr j; incr i ;incr k} {
    set link_map($i,$j,$k) ...
}
Run Code Online (Sandbox Code Playgroud)

这将创建一个使用逗号连接三个值的字符串,并将结果用作键.


使用foreach ... break爆炸列表是一个巧妙的技巧,但如果你有Tcl 8.5或更高版本,请lassign $list v1 v2 v3改用.

  • 在Tcl中使用的另一个多维范例是使用嵌套列表和`lset`. (2认同)