2

Given:

my @main_array = ();

my @sub_array1 = ( 1, 2, 3, 4, 5);
my @sub_array2 = ( "a", "b", "c", "d", "e" );

push @main_array, \@sub_array1;
push @main_array, \@sub_array2;
print "size of main_array is ",scalar(@main_array),"\n";

I want to foreach through the main_array and then foreach through the two arrays that it contains I have no idea what the syntax is for that.

Don't know if this is correct, but Perl seems to want a $ in the front of the foreach variable here. (doesn't like @$sub_array) I would also like to know the syntax to for loop through the main and sub as well.

foreach my $sub_array (@main_array)
{
   print $sub_array; # prints ARRAY(0x213232)
   # loop through each item in sub array
   #foreach ... 
}

Edit: So to summarize the answers given below (thanks to all):

use strict;
use warnings;

my @main_array = ();

my @sub_array1 = ( 1, 2, 3, 4, 5);
my @sub_array2 = ( "a", "b", "c", "d", "e" );

push @main_array, \@sub_array1;
push @main_array, \@sub_array2;
print "size of main_array is ",scalar(@main_array),"\n";

print "--------foreach ---------------------\n";

foreach my $sub_array (@main_array)
{
   print "Sub array has ", scalar(@{$sub_array})," elements\n";
   foreach my $value ( @{$sub_array})
   {
      print "value: ",$value,"\n";
   }
}

print "--------------- for ----------------------- \n";

for (my $i = 0; $i < scalar(@main_array); $i++)
{
    my $sub_array = $main_array[$i];
    print "Sub array has ", scalar( @{$sub_array}), " elements\n";
    for (my $j = 0; $j < scalar( @{$sub_array}); $j++)
    {
       print "value: ", $sub_array->[$j],"\n";
    }
}
2
  • for my $v (@$sub_array) { .. } Commented Dec 9, 2014 at 15:22
  • You are storing array references in your main array. So in your loop your variable $sub_array is an array reference. Commented Dec 9, 2014 at 15:25

2 Answers 2

6
my $sz = 0;
for my $outer (@main_array) {
  for my $inner( @{ $outer } ) {
     print $inner;
     $sz++;
    }
  }

print "total number of all values held in main_array is $sz \n";

perllol and perldsc are good sources of info on these matters

For debugging use Data::Dumper; print Dumper(\@main_array) is useful

Hope this helps

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the reply - if I do foreach my $value ( @{$sub_array}) { print $value,"\n"; } it prints 4 values for each inner array, whereas they both have 5 values. How would you access a single element of the inner array?
using your example data print $main_array[0]->[1] gives 2 and print $main_array[1]->[1] gives b. Please read perldsc and perllol, they explain it better than I can!
@Scooter Edit your question to show the exact code you're using that only prints 4 out of 5 array elements. The code Vorsprung gave prints all values in each inner array, so you must be doing something different. perl -wE 'my @array = ([1..5],["a".."e"]); foreach my $outer (@array) { foreach my $inner (@$outer) { say $inner } }'
@ThisSuitIsBlackNot Sorry, my bad. the first element was at the end of a previous line and I missed it. They all print.
3

The solution is traditional nested loops:

use warnings;
use strict;

my @sub_array1 =   ( 1, 2, 3, 4, 5  );
my @sub_array2 = qw/ a  b  c  d  e  /;
my @main_array = ( \@sub_array1, \@sub_array2 );

print "\@main_array has ", scalar @main_array, " elements.\n\n\n";

foreach my $outer ( @main_array ) {
    print "Sub array has ", scalar @{$outer}, " elements:\t";
    foreach my $inner ( @$outer ) {
        print "($inner) ";
    }
    print "\n";
}

This will produce the following output:

@main_array has 2 elements.


Sub array has 5 elements:   (1) (2) (3) (4) (5) 
Sub array has 5 elements:   (a) (b) (c) (d) (e) 

To access individual elements directly, you could say:

print $main_array[1][3], "\n";

...which would produce "d".

Or within the outer loop you could do this:

for my $outer ( @main_array ) {
    print join( ' ', $outer->[0], $outer->[1], $outer->[2], $outer->[3], $outer->[4] ), "\n";
    # prints first five elements.
}

...but that's kind of silly since it's not as flexible as just using an inner loop.

7 Comments

I assume you chose print join( ' ', $outer->[0], ... to illustrate -> syntax, since it's easier to just dereference: print join( ' ', @$outer );
@ThisSuitIsBlackNot I chose that syntax to illustrate to Scooter the answer to his followup question where he asked, "How would you access a single element of the inner array?"
@G.Cito There are many times in Perl where an explicit nested loop can be replaced by some other construct that is more idiomatic. But even join "\t", @array is a loop internally.
@G.Cito If you want to post a question that is more philosophical in nature, it's probably more on-topic on PerlMonks. Here it would probably just get closed. There, it would probably provoke worthwhile discussion.
Optimize for the developer's sanity first, then later for specific needs such as run time, runtime space, resource conservation, etc.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.