Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to set 2 dimensional arrays in TCL

4,477 views
Skip to first unread message

balaram baral

unread,
Oct 21, 2013, 3:33:59 AM10/21/13
to
I am trying to do the below

set l 0
set m 0

set dbout($l)($m) $modelnum

echo $dbout($l)($m)

but this gives me an error .

can't read "dbout(0)": no such element in array
while executing
"echo $dbout($l)($m)"

Can anyone please suggest what am i doing wrong here ? I just started with TCL and i am stuck .

Regards,
Balaram.

Arjen Markus

unread,
Oct 21, 2013, 3:40:48 AM10/21/13
to
Well, first of all, to print something to the screen/console, use the puts
command - echo is not part of standard Tcl:

puts $dbout($l)

Second, arrays in Tcl are so-called associative arrays - not the sort of arrays with numerical indices you find in C, Java, Fortran or MATLAB and others.

To create a "two-dimensional" array, use a unique separator such as a comma:

set dbout($l,$m) $modelnum

(You can use other characters as well, as the entire string between the parentheses is used as a key)

Regards,

Arjen

Andreas Leitgeb

unread,
Oct 21, 2013, 4:23:03 AM10/21/13
to
balaram baral <balara...@gmail.com> wrote:
> I am trying to do the below
> set l 0
> set m 0
> set dbout($l)($m) $modelnum

Arjen already posted the explanation (Namely: arrays have only one
dimension, but that can be any string, not just numbers).
My post is to point out what is happening in your example.

% array names dbout
0)(0
The "set" command caused everything between first "(" and last ")"
to be treated as index.

Essentially, you used ")(" as an index separator. This works,
whenever you pass the indexed array name as a single argument to
some command.

> echo $dbout($l)($m)

Retrieval syntax with "$" is a bit more tricky: it tries to find the close
parentheses matching the open parentheses, and hits on the "separator".

You could avoid this either by using a different separator (Arjen
suggested a comma) already when setting the array element,

or use "set" also for retrieving:
puts [set dbout($l)($m)]

Yet another way to avoid the ")(" separator being misinterpreted as
end of index: (not recommended, just for putting the finger on the problem)

set lm "$l)($m"
puts $dbout($lm)


Arjen Markus

unread,
Oct 21, 2013, 6:00:11 AM10/21/13
to
On Monday, October 21, 2013 10:23:03 AM UTC+2, Andreas Leitgeb wrote:

> My post is to point out what is happening in your example.
>
> % array names dbout
> 0)(0
> The "set" command caused everything between first "(" and last ")"
> to be treated as index.
>

I was wondering about that :). Thanks for the explanation - simple and consistent, actually, but I did not think of the possibility of such a key.

Regards,

Arjen

Robert Heller

unread,
Oct 21, 2013, 3:12:17 PM10/21/13
to
You should be aware: Tcl's 'arrays' are not arrays in the C or FORTRAN sense
and are not implemented as 'values', so cannot be used like C arrays either.
(C does not have multi-dimensional arrays either, but it can have arrays of
pointers, which can be indexed as if they were 2 (or more) dimensional
arrays.) They really just single-dimensional 'hash tables', implemented as a
special variable type. Multi-dimensional 'arrays' can be 'faked' by creating
keys from multiple 'indexes' (index values) strung together into strings.

>
> Arjen
>

--
Robert Heller -- 978-544-6933 / hel...@deepsoft.com
Deepwoods Software -- http://www.deepsoft.com/
() ascii ribbon campaign -- against html e-mail
/\ www.asciiribbon.org -- against proprietary attachments



Andreas Kupries

unread,
Oct 22, 2013, 1:21:48 AM10/22/13
to
http://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html
http://www.tcl.tk/man/tcl8.5/tutorial/Tcl22.html

--
So long,
Andreas Kupries <akup...@shaw.ca>
<http://www.purl.org/NET/akupries/>
Developer @ <http://www.activestate.com/>

Tcl'2013, Sep 23-27, New Orleans, LA, USA. http://www.tcl.tk/community/tcl2013/
EuroTcl'2013, Jul 6-7, Munich, GER
GSoC 2013, add your ideas to http://wiki.tcl.tk/36464
-------------------------------------------------------------------------------

h.ol...@geon.nl

unread,
Oct 22, 2013, 8:52:40 AM10/22/13
to
On Monday, October 21, 2013 9:33:59 AM UTC+2, balaram baral wrote:
Tcl has no 2-dimensional arrays in the strict sense.
You could do:

set dbout($l,$m) $modelnum
parray dbout

It al depends what you would want to do, but for 2-dimensional data you could consider:
(1) nested lists (list of lists)
(2) lists in arrays
(3) dicts
(4) photo images
(5) classes

Regards,
Harm Olthof

tcltk-d

unread,
Oct 22, 2013, 8:07:03 PM10/22/13
to
Hi,all. I have thunder stroken.

Olthof> (1) nested lists (list of lists)
Olthof> (2) lists in arrays
Olthof> (3) dicts
Olthof> (4) photo images
Olthof> (5) classes

Tcl may not needs even those concepts.
Tcl is built only by "strings"(or "symbols").

How about this code?

foreach {x v p} {1 1 , 2 3 , 3 99 ,} {
set a$x $v;
}

for {set i 1} {1} {incr i} {
if ![info exists a$i] break;
puts "a$i = [set a$i]"
}

thanks.

tomás zerolo

unread,
Oct 23, 2013, 11:55:38 AM10/23/13
to
Depends on what you want to achieve. If you use "nested lists",
contemporary implementations of Tcl will take care that they are
implemented as arrays "behind the scenes" (most of the time, for
sensible usage patterns, that is). If your arrays consist of thousands
of entries, you'll appreciate that.

tomas@rasputin:~$ tclsh
tclsh8.5 [~] set a { {1 1} {2 3} {3 99} }
{1 1} {2 3} {3 99}
tclsh8.5 [~]lindex $a 0 0
1
tclsh8.5 [~]lindex $a 2 1

tclsh8.5 [~]time {for {set i 0} {$i < 1000000} {incr i} {lappend mill $i}} 1
1949908 microseconds per iteration
tclsh8.5 [~]time {lindex $mill 500000} 1
39 microseconds per iteration

Admittedly, constructing the list stepwise with lappend is not the
fastest thing :-)

(Accessing one variable is a tad faster than lindex, though)

Regards
-- tomás
0 new messages