Solved

Iterating over a 2D array

Posted on 2008-06-12
6
1,159 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
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

There are many situations when we need to display the data in sorted order. For example: Student details by name or by rank or by total marks etc. If you are working on data driven based projects then you will use sorting techniques very frequently.…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
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…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

708 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now