ZetCode

Tcl 中的数组

最后修改于 2023 年 10 月 18 日

在本 Tcl 编程教程中,我们将介绍数组。我们初始化数组并从中读取数据。

Tcl 数组是一组变量的集合。每个变量可以保存任何值,并且数组由任意值索引。键值对是无序的。Tcl 数组是一个关联数组。

创建数组

Tcl 数组可以使用 setarray set 命令创建。

#!/usr/bin/tclsh

set names(1) Jane
set names(2) Tom
set names(3) Elisabeth
set names(4) Robert
set names(5) Julia
set names(6) Victoria

puts [array exists names]
puts [array size names]

puts $names(1)
puts $names(2)
puts $names(6)

我们创建一个名为 names 的数组。数字是键,名称是数组的值。

set names(1) Jane

在此行中,我们将值 Jane 设置为数组键 1。我们稍后可以通过键引用该值。

puts [array exists names]

array exists 命令确定提供的参数是否为数组。

puts [array size names]

我们使用 array size 命令获取数组的大小。

puts $names(1)

我们通过键从数组中访问一个值。

$ ./names.tcl
1
6
Jane
Tom
Victoria

在第二个示例中,使用 array set 命令创建数组。

#!/usr/bin/tclsh

array set days {
    1 Monday
    2 Tuesday
    3 Wednesday
    4 Thursday
    5 Friday
    6 Saturday
    7 Sunday
}

set n [array size days]

puts $days(1)
puts "array has $n elements" 

我们创建一个 days 数组。它有 7 个键值对。

$ ./days.tcl 
Monday
array has 7 elements

示例输出。

数组是变量的集合

与列表或字典不同,数组中的项目是变量。这意味着我们可以引用它们。

#!/usr/bin/tclsh

array set days {
    1 Monday
    2 Tuesday
    3 Wednesday
    4 Thursday
    5 Friday
    6 Saturday
    7 Sunday
}

upvar #0 days(1) mon
upvar #0 days(2) tue
upvar #0 days(3) wed

puts $mon
puts $tue
puts $wed

在脚本中,使用 upvar 命令引用 days 数组的三个变量。

upvar #0 days(1) mon

mon 变量引用索引为 1 的变量。upvar 命令的第一个参数是上层,其中 #0 表示顶层。也就是说,days 数组和 mon 变量都位于同一个全局命名空间中。

puts $mon

在这里,我们通过 mon 变量引用 days 数组的一个项目。

$ ./colvar.tcl 
Monday
Tuesday
Wednesday

示例输出。

array get 命令

array get 命令返回一个列表,其中包含数组的元素对。

#!/usr/bin/tclsh

array set days {
    Peter 34
    Jane 17
    Lucy 28
    Mark 43
    Anthony 36
}

puts [array get days]

该示例创建一个数组,并使用 array get 命令打印其键值对。

$ ./arrayget.tcl 
Peter 34 Anthony 36 Lucy 28 Jane 17 Mark 43

遍历数组

在以下示例中,我们展示了如何遍历数组。

#!/usr/bin/tclsh

array set days {
    1 Monday
    2 Tuesday
    3 Wednesday
    4 Thursday
    5 Friday
    6 Saturday
    7 Sunday
}

foreach {n day} [array get days] {

    puts "$n -> $day"
}

该示例创建一个数组,并使用 array get 命令打印其键值对。

foreach {n day} [array get days] {

array get 命令返回一个键、值元素的列表,可以使用 foreach 命令进行迭代。

$ ./days2.tcl 
4 -> Thursday
5 -> Friday
1 -> Monday
6 -> Saturday
2 -> Tuesday
7 -> Sunday
3 -> Wednesday

这里我们有 days2.tcl 脚本的输出。请注意,元素对没有排序。

以下脚本使用 array names 命令来遍历数组。

#!/usr/bin/tclsh

array set nums { a 1 b 2 c 3 d 4 e 5 }

puts [array names nums]

foreach n [array names nums] {

    puts $nums($n)
}

我们创建一个简单的 nums 数组并循环遍历它。

array set nums { a 1 b 2 c 3 d 4 e 5 }

我们定义一个简单的数组。

puts [array names nums]

array names 返回一个包含数组中所有元素的名称(键)的列表。

foreach n [array names nums] {

    puts $nums($n)
}

我们使用键来获取值。

$ ./getnames.tcl 
d e a b c
4
5
1
2
3

前面的示例使用数组的副本,因此不太适合处理大型数组。数组搜索工具更有效。

#!/usr/bin/tclsh

array set days {
    1 Monday
    2 Tuesday
    3 Wednesday
    4 Thursday
    5 Friday
    6 Saturday
    7 Sunday
}

set start [array startsearch days]

while {[array anymore days $start]} {
    set key [array nextelement days $start]

    puts $days($key)
}
 
array donesearch days $start

我们使用数组搜索命令来迭代一个简单的数组。

set start [array startsearch days]

array startsearch 命令引用数组的开头。

while {[array anymore days $start]} {

如果数组搜索中还有要处理的元素,array anymore 命令将返回 1。

set key [array nextelement days $start]

array nextelement 命令返回数组中下一个元素的名称。

array donesearch days $start

array donesearch 命令终止数组搜索并销毁与该搜索关联的所有状态。

删除元素

在本章的最后一个示例中,我们将展示如何从数组中删除元素。

#!/usr/bin/tclsh

set names(1) Jane
set names(2) Tom
set names(3) Elisabeth
set names(4) Robert
set names(5) Julia
set names(6) Victoria

puts [array size names]
unset names(1)
unset names(2)

puts [array size names]

我们创建一个 names 数组。我们使用 unset 命令从数组中删除项目。我们在删除两个项目之前和之后检查数组的大小。

set names(1) Jane

set 命令用于在数组中创建一个项目。

unset names(1)

我们使用 unset 命令从数组中删除键为 1 的元素。

$ ./removing.tcl 
6
4

一开始,数组中有 6 个元素。删除两个元素后,剩下 4 个元素。

在本 Tcl 教程中,我们使用了 Tcl 数组。