如何在foreach中获取列表长度
how to get lists length within foreach
set listA "A B C"
set listB "D E"
set lists "listA listB"
foreach l $lists { puts "$l: [llength $l]"}
它打印
listA: 1
ListB: 1
而不是
listA: 3
listB: 2
问题是foreach循环中的$l
是一个变量的name,不是一个变量的value变量。
当您有一个变量包含另一个变量的名称(而非值)时,它会产生一个重定向问题,您可以通过几种方法解决该问题。我喜欢使用 set
和一个参数来检索变量名称的值:
set listA "A B C"
set listB "D E"
set lists "listA listB"
foreach l $lists {
set this_list [set $l]
puts "$l: [llength $this_list]"
}
另一种选择是将多个列表保存到关联数组中...
set my_array(listA) "A B C"
set my_array(listB) "D E"
set lists "listA listB"
foreach l $lists {
set this_list $my_array($l)
puts "$l: [llength $this_list]"
}
..或在字典中:
set my_dict [dict create listA "A B C" listB "D E"]
set lists [dict keys $my_dict]
foreach l $lists {
set this_list [dict get $my_dict $l]
puts "$l: [llength $this_list]"
}
以上所有例子中,创建变量this_list
并不是必须的,只是强调获取$l
.
中包含的变量名的值
另一种将字符串映射到具有该名称的变量的方法是使用堆栈级别为 0 的 upvar
:
#!/usr/bin/env tclsh
set listA {A B C}
set listB {D E}
set lists {listA listB}
foreach l $lists {
upvar 0 $l this_list
puts "$l: [llength $this_list]"
}
(当你处理一个 proc 时会更有用,该 proc 希望在其调用者的范围内使用一个按名称传递的变量,但如果需要它也可以在相同的堆栈级别工作)
set listA "A B C"
set listB "D E"
set lists "listA listB"
foreach l $lists { puts "$l: [llength $l]"}
它打印
listA: 1
ListB: 1
而不是
listA: 3
listB: 2
问题是foreach循环中的$l
是一个变量的name,不是一个变量的value变量。
当您有一个变量包含另一个变量的名称(而非值)时,它会产生一个重定向问题,您可以通过几种方法解决该问题。我喜欢使用 set
和一个参数来检索变量名称的值:
set listA "A B C"
set listB "D E"
set lists "listA listB"
foreach l $lists {
set this_list [set $l]
puts "$l: [llength $this_list]"
}
另一种选择是将多个列表保存到关联数组中...
set my_array(listA) "A B C"
set my_array(listB) "D E"
set lists "listA listB"
foreach l $lists {
set this_list $my_array($l)
puts "$l: [llength $this_list]"
}
..或在字典中:
set my_dict [dict create listA "A B C" listB "D E"]
set lists [dict keys $my_dict]
foreach l $lists {
set this_list [dict get $my_dict $l]
puts "$l: [llength $this_list]"
}
以上所有例子中,创建变量this_list
并不是必须的,只是强调获取$l
.
另一种将字符串映射到具有该名称的变量的方法是使用堆栈级别为 0 的 upvar
:
#!/usr/bin/env tclsh
set listA {A B C}
set listB {D E}
set lists {listA listB}
foreach l $lists {
upvar 0 $l this_list
puts "$l: [llength $this_list]"
}
(当你处理一个 proc 时会更有用,该 proc 希望在其调用者的范围内使用一个按名称传递的变量,但如果需要它也可以在相同的堆栈级别工作)