# Iterating over a 2D array

Hi,

When you're using the following syntax to iterate a 2D array:

for (\$it (@my2dArray)) {

for (\$j = 0; \$j < @\$it; \$j++) {
}
}

I'm assuming that:

for (\$it (@my2dArray)

means create a reference to the array called \$it, that points to the current row in the loop. Then you can access an element in the row being referenced like:

\$it->[\$columnIndexYouWant];

This funky statement:

\$j < @\$it

specifically the:

@\$it

I don't know how to explain - I know it is giving you the number of columns in the row referenced by \$it. I know in a 1D array you can just do this:

my @my1dArray = (0,1,2);
for (my \$i = 0; \$i < @my1dArray; \$i++)

and the

< @my1dArray

will give you the size of the array. So in the 2d array though, you need the dollar sign since \$it is a scalar which is a reference to the row, then you put the @ symbol in front of it to signal that you want it interpreted as the entire 1d array of the row, so perl gives you the size?

This is quite verbose compared to C!

Thanks
###### Who is Participating?

x

Commented:
> 1) Does  the first line create a *reference* to the 2d array? I thought for references you needed to
no

\$myref = \@my2dArray;

or is:

for (\$it (@my2dArray)) {

an acceptable short-hand for that?
for (\$it (@my2dArray)) {
is not a shorthand for
\$myref = \@my2dArray;

\$it becomes an alias to each element of @my2dArray
and if the elements of @my2dArray are references to arrays, as suggested by the name "my2dArray"
then \$lt will be a reference to those arrays

2) The second line:

\$j < @\$it;

If \$it is a reference to the current row being iterated, then we need to put a \$ in front of it, because references are scalars and need the \$, and then we put the @ in front to  have perl interpret it as wanting to get:
the size of the array referenced by \$it

\$it is a scalar containing a reference,
@ dereferences it to get the array, who's value in scalar context on the right of a < is the number of elements in the array

see
perldoc perllol
0

Commented:
The thing with perl is each row could have a different number of columns.  So for each row, you need to iterate over however many columns there are in that row.

I'm not really sure what your question was... but there are several things you could do, depending on what you want to do.  Here are several examples of ways to display 2d array (commonly called array-of-array):
``````my @array2d = (['a1','b1','c1'], ['a2', 'b2', 'c2', 'd2'], ['a3', 'b3'], ['a4', 'b4', 'c4', 'd4']);

#print each row on a line, with each column separated by comma
print join("\n", map{join(",", @\$_)}@array2d) . "\n";
print "\n";

#Do the same:
foreach my \$row (@array2d) {
print join(",", @\$row) . "\n";
}
print "\n";

#Do the same:
for(my \$rowi=0; \$rowi<=\$#array2d; \$rowi++) {
for(my \$coli=0; \$coli<=\$#{\$array2d[\$rowi]}; \$coli++) {
print "," unless \$coli==0;
print \$array2d[\$rowi][\$coli];
}
print "\n";
}
print "\n";
``````
0

Author Commented:
Yeah I guess I was asking more if my original post is correct (is what I said right?). Really these two lines:

for (\$it (@my2dArray)) {
for (\$j = 0; \$j < @\$it; \$j++) {

1) Does  the first line create a *reference* to the 2d array? I thought for references you needed to do:

\$myref = \@my2dArray;

or is:

for (\$it (@my2dArray)) {

an acceptable short-hand for that?

2) The second line:

\$j < @\$it;

If \$it is a reference to the current row being iterated, then we need to put a \$ in front of it, because references are scalars and need the \$, and then we put the @ in front to  have perl interpret it as wanting to get:

the size of the array referenced by \$it

It's just confusing with all the different ways of doing the same thing.

Thanks
0

Commented:
DJ,

1)

\$myref = \@my2dArray;

is NOT the same as:

for (\$it (@my2dArray))

which really should be: for \$it (@my2dArray)

anyhow \$myref is a reference of the array itself not a reference of the elements within the array which is what the "for" does, iterate through the elements, that happen to be references to an array. What you are asking as an acceptable equivalence would be:

\$it=\$my2dArray[0];
\$it=\$my2dArray[1];
\$it=\$my2dArray[2];
.
.

2) what you describe is correct, to get the size of an array which is a reference.

What is probably confusing you is that @var can be the array itself and the size of the array. You need to think in terms of the context where the variable appears.

for \$it (@my2dArray)

expects the value withing the () to be an array, so perl treat it as such.

whereas

\$j < @\$it

or

\$i < @my1dArray

expects the value to the right of the "<" to be an scalar, the variable actually is the array but is in a scalar context so it returns the number of elements, not the array itself.

0

Commented:
If you try to write C style code in Perl, it may seem verbose to write extra \$ that wouldn't be there in C
(Although @my2dArray seems less verbose than C's (sizeof(my2dArray)/sizeof(*my2dArray))
but if you write Perl style code more like
for \$it ( @my2dArray ){
print "\$_\n" for @\$it;
}
it can be less verbose than writing Perl style code in C
0

Commented:
It might be clearer to think of it this way:

foreach my \$array (@my2dArray) {
for (\$j = 0; \$j < @{\$array} \$j++) {
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.