2

我正在尝试动态填充数组,而不是通过运行如下计数器手动设置它:

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 }
}

并希望访问如下变量:

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"
}

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

4

1 回答 1

6

对我来说,你的真实身份并不是很明显想要做什么并不是很明显,所以我会做一些猜测。

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

另请注意,在您的示例中jik变量似乎在每次迭代中具有相同的值。假设它只是真实世界代码的剩余部分,但否则只有一个变量就足够了。

猜一猜:您想将每个键映射到值列表。这不会像在您的示例中那样工作,因为在 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"
}

猜猜二:从你对显示的使用来看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"
}

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

更新

猜三个。您将我们的问题标记为multidimensional-array。我在您的片段中看不到任何多维性的痕迹,但如果您真的想要它,Tcl 中通常的范例是使用复合键。例如,如果您想通过 的值来键入数组ji并且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) ...
}

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


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

于 2012-11-09T20:31:38.377 回答