How to implement two dimensional arrays in tcl

Pallavi Venkatesh picture Pallavi Venkatesh · Jun 8, 2017 · Viewed 8.8k times · Source

Need assistance in creating two dimensional arrays.

I need to create the below scenario

nblist_0 = {1,2,3,4}
nblist_1 = {3,7,5,9,1}
nblist_2 = {7,4,9,2,5}
nblist_3 = {1,2,4,6}
nblist_4 = {1,5,4}
... 

Since my logic hereafter follows the above two dimensional array, I also need the logic to access the individual data (just like an array). Kindly help!!

Answer

Donal Fellows picture Donal Fellows · Jun 8, 2017

There are two recommended ways. One is to construct a list of lists and to use the multi-index versions of lindex and lset, and the other is to construct composite keys to use with associative arrays.

Nested Lists

# Setup...
set nblist {
    {1 2 3 4}
    {3 7 5 9 1}
    {7 4 9 2 5}
    {1 2 4 6}
    {1 5 4}
}

# Reading...
set row 1
set column 3
set value [lindex $nblist $row $column]

# Writing...
lset nblist $row $column [expr {$value + 17}]

You can add new rows to the table with lappend, and (in Tcl 8.6) extend a row by an element with lset nblist $rowidx end+1 $initval

Iteration of the rows or the columns of one row with foreach is trivial.

Composite Keys

# Setup...
array set nblist {
    0,0 1 0,1 2 0,2 3 0,3 4
    1,0 3 1,1 7 1,2 5 1,3 9 1,4 1
    2,0 7 2,1 4 2,2 9 2,3 2 2,4 5
    3,0 1 3,1 2 3,2 4 3,3 6
    4,0 1 4,1 5 4,2 4
}

# Reading...
set row 1
set column 3
set value $nblist($row,$column)

# Writing...
set nblist($row,$column) [expr {$value + 17}]

With this approach, the elements are fundamentally entirely unordered and your keys are fundamentally strings, but you can access individual elements fairly simply. However, there's no concept of a row or a column; iteration over the contents of the array will be annoying.