I want to be accomplish something like this ...
set tmp(array1) $array1
set tmp(array2) $array2
... where array1 and array2 are array variables. Only problem is the
tcl interpreter gives me an error when I try to get the value of an
array variable with the dollar "$" sign.
Right now I am forced to use a list of lists, but this slows my code way
down.
Arturo Fagundo
The two other possibities are:
1) Use an array of lists (or keyed lists). This way the penalty is linear
not cubic.
2) Use a convention on the index like:
foreach k [array names array1] {set tmp(array1-$k) $array1($k)}
/Flemming
Arturo Fagundo wrote:
>
> Anyone know how to generate an array of arrays in Tcl? I can generate
> an array of strings which corresponds to a set of arrays, but I want to
> generate the array of arrays in a procedure and have the resulting array
> of arrays passed back to the global scope.
>
> I want to be accomplish something like this ...
>
> set tmp(array1) $array1
> set tmp(array2) $array2
>
> ... where array1 and array2 are array variables. Only problem is the
> tcl interpreter gives me an error when I try to get the value of an
> array variable with the dollar "$" sign.
>
> Right now I am forced to use a list of lists, but this slows my code way
> down.
I suppose you try to do that kind of stuff:
####
% array set a1 {1 a 2 b 3 c}
% array set a2 {1 d 2 e 3 f}
% parray a1
a1(1) = a
a1(2) = b
a1(3) = c
% parray a2
a2(1) = d
a2(2) = f
a2(3) = g
% set a(1) a1
a1
% set a(2) a2
a2
% set a(1)(1)
can't read "a(1)(1)": no such element in array
####
That's because Tcl looks for an element named 1)(1, ie the element's name
is enclosed between the _outmost_ parentheses.
So instead of "set a(1)(1)", use:
###
% set [set a(1)](1)
a
% set [set a(2)](1)
d
###
That way you can put arrays in arrays. Actually, you only put the array's
name in the first array.
Another trick is to use a formatting convention to name array elements:
###
% set b(1)(1) blah
blah
% set b(1)(1)
blah
% set i 1; set j 1; set b($i)($j)
blah
% array names b
1)(1
###
Note that you get a Tcl array that looks like a multidimensional array,
but really is monodimensional, with odd names. This is not the same as
putting an array in an array, because you can't get subarrays. For example:
###
% set b(1)
can't read "b(1)": no such element in array
###
That's because there isn't an element named "1" in array b.
One last solution is to use lists in Tcl8. List access should be in O(1)
in Tcl8, whereas it was in O(n) in prior versions.
See you, Fred
--
Frederic BONNET fbo...@irisa.fr
Ingenieur Ecole des Mines de Nantes/Ecole des Mines de Nantes Engineer
IRISA Rennes, France - Projet Solidor/Solidor Project
------------------------------------------------------------------------
Tcl: can't leave | "Theory may inform but Practice convinces."
$env(HOME) without it! | George BAIN
Frederic Bonnet wrote:
[...]
> Another trick is to use a formatting convention to name array elements:
>
> ###
> % set b(1)(1) blah
> blah
> % set b(1)(1)
> blah
> % set i 1; set j 1; set b($i)($j)
> blah
> % array names b
> 1)(1
> ###
>
> Note that you get a Tcl array that looks like a multidimensional array,
> but really is monodimensional, with odd names. This is not the same as
> putting an array in an array, because you can't get subarrays. For example:
[...]
Well, maybe that's not a good idea after all: "set b($i)($j)" works, but
"puts $b($i)($j)" doesn't. You have to use "puts [set b($i)($j)]" and use
set everywhere. So you get the same annoyance as with the first solution.
I really wonder why Tcl accepts "set b($i)($j)" and why it refuses "$b($i)($j)".
I think it's a bit brain-dead on this point, the substitution rules should be
the same. Or maybe there's some arcane reason for that.
You can still use this solution, but with comma-separated names instead:
set b(1,1)
Don't put spaces around the comma, though.
This works:
% puts $b($i\)($j)
fred
Which isn't nearly as bad as using [set ...] everywhere. And you can get sub
arrays on the first dimension:
% array get b 1\)*
1)(1 fred
Ross
--
Ross J. Reedstrom, Ph.D., <r...@bioc.rice.edu> NSF Postdoctoral Fellow
W.M. Keck Center for Computational Biology
Department of Biochemistry & Cell Biology
Rice University, 6100 S. Main St., Houston, TX 77005