TCL - 如何存储和打印值表?

时间:2013-12-16 22:10:24

标签: tcl

我知道你可以在tcl中“破解”嵌套关联数组,而且我也知道使用字典(我没有经验),你可以很容易地嵌套它们。我试图找到一种方法来存储具有两个变量的函数的值,然后在最后我只想打印出两个变量(列和行标题)的表,其中包含单元格中的函数值。我可以做到这一点,但它既不简洁也不高效。

这是应该打印的内容。行是b的值,列是a的值(1,2,3,4,5为简单起见):

                          b
          1       2       3       4       5
    1  y(1,1)  y(1,2)  y(1,3)  y(1,4)  y(1,5)
    2  y(2,1)  y(2,2)  y(2,3)  y(2,4)  y(2,5)
  a 3  y(3,1)  y(3,2)  y(3,3)  y(3,4)  y(3,5)
    4  y(4,1)  y(4,2)  y(4,3)  y(4,4)  y(4,5)
    5  y(5,1)  y(5,2)  y(5,3)  y(5,4)  y(5,5)

为了存储这个,我想我会简单地在a和b上做两个嵌套for循环,并以某种方式将结果存储在嵌套字典中。就像有一个带有5个条目的字典,每个b的值为1,并且每个条目是b的每个值的另一个字典。

要打印它,我能想到的唯一方法是只显式打印每个表格行并调用每个字典条目。我不太熟悉tcl的输出格式,但我可以在那里管理。

有人能想出更优雅的方法吗?

3 个答案:

答案 0 :(得分:5)

以下是一些有关如何使用struct::matrix包的示例。

示例1 - 简单创建/显示

package require struct::matrix
package require Tclx

# Create a 3x4 matrix
set m [::struct::matrix]
$m add rows 3
$m add columns 4

# Populate data
$m set rect 0 0 {
    {1 2 3 4}
    {5 6 7 8}
    {9 10 11 12}
}

# Display it
puts "Print matrix, cell by cell:"
loop y 0 [$m rows] {
    loop x 0 [$m columns] {
        puts -nonewline [format "%4d" [$m get cell $x $y]]
    }
    puts ""
}

输出

Print matrix, cell by cell:
   1   2   3   4
   5   6   7   8
   9  10  11  12

讨论

  • 在脚本的第一部分,我创建了一个矩阵,添加了3行和4列 - 一个直接的过程。
  • 接下来,我打电话给set rect用数据填充矩阵。根据您的需要,您可能需要查看set cellset columnset row。有关详细信息,请参阅struct::matrix的{​​{3}}。
  • 当涉及到显示矩阵时,我更喜欢for包中的loop命令,而不是使用Tcl的Tclx命令,它更易于阅读和使用。< / LI>

示例2 - 从CSV文件中读取

package require csv
package require struct::matrix
package require Tclx

# Read a matrix from a CSV file
set m [::struct::matrix]
set fileHandle [open data.csv]
::csv::read2matrix $fileHandle $m "," auto
close $fileHandle

# Displays the matrix
loop y 0 [$m rows] {
    loop x 0 [$m columns] {
        puts -nonewline [format "%4d" [$m get cell $x $y]]
    }
    puts ""
}

数据文件data.csv:

1,2,3,4
5,6,7,8
9,10,11,12

输出

   1   2   3   4
   5   6   7   8
   9  10  11  12

讨论

  • csv包提供了一种从CSV文件读取矩阵的简单方法。
  • 操作的核心在::csv::read2matrix命令中,但在此之前,我必须创建一个空矩阵并打开文件进行阅读。
  • 显示矩阵的代码与前面的示例相同。

结论

虽然struct::matrix包装起初看起来很复杂;我只需要学习一些命令即可开始使用。

答案 1 :(得分:2)

优雅在旁观者眼中:)

使用基本的核心Tcl,我认为你理解你的选择。当涉及表格式数据时,数组或嵌套字典都有笨重的边缘。

如果您愿意探索扩展(并且Tcl就是扩展),那么您可以考虑使用标准Tcl库中的矩阵包。它将行和列作为关键概念处理。如果你需要对表格数据进行转换,那么我建议使用TclRAL,这是一个定义关系数据类型的关系代数库,它将处理所有类型的表格数据并在其上提供大量操作。或者,您可以尝试像SQLite这样的东西,它也可以处理表格数据,提供操作它并具有强大的持久存储。 Tcl wiki将引导您了解所有这些扩展的详细信息。

然而,如果这些看起来对你的品味来说太重了,或者如果你不想受到学习曲线的影响,卷起你的袖子,敲打一个阵列或嵌套的字典解决方案,虽然当然是特别的,但是可能不那么难。优雅?嗯,那是你判断的。

答案 2 :(得分:2)

如果你有紧凑的数字索引,嵌套列表对于8.4以后的表格数据(使用多索引lindexlset)的工作相当合理。 8.5 lrepeat也适用于构建初始矩阵。

set mat [lrepeat 5 [lrepeat 5 0.0]]

lset mat 2 3 1.3

proc printMatrix {mat} {
    set height [llength $mat]
    set width [llength [lindex $mat 0]]
    for {set j 0} {$j < $width} {incr j} {
        puts -nonewline \t$j
    }
    puts ""
    for {set i 0} {$i < $height} {incr i} {
        puts -nonewline $i
        for {set j 0} {$j < $width} {incr j} {
            puts -nonewline \t[lindex $mat $i $j]
        }
        puts ""
    }
}
printMatrix $mat

您一定要考虑使用tcllib的struct::matrixreport软件包。