Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Iterating over a 2D array

Posted on 2008-06-12
6
1,168 Views
Last Modified: 2008-06-13
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
0
Comment
Question by:DJ_AM_Juicebox
6 Comments
 
LVL 39

Expert Comment

by:Adam314
ID: 21771697
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";

Open in new window

0
 

Author Comment

by:DJ_AM_Juicebox
ID: 21771928
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
 
LVL 7

Expert Comment

by:rugdog
ID: 21772362
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
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 84

Expert Comment

by:ozo
ID: 21773282
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
 
LVL 84

Accepted Solution

by:
ozo earned 500 total points
ID: 21773352
> 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
 
LVL 17

Expert Comment

by:mjcoyne
ID: 21775648
It might be clearer to think of it this way:

foreach my $array (@my2dArray) {
   for ($j = 0; $j < @{$array} $j++) {
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

On Microsoft Windows, if  when you click or type the name of a .pl file, you get an error "is not recognized as an internal or external command, operable program or batch file", then this means you do not have the .pl file extension associated with …
In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

790 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question