I have the code similar to below:
my @array1 = (); #2d array to be used
my $string1 = "blank1";
my $string2 = "blank2";
my $string3 = "blank3";
my @temp = ($string1, $string2, $string3);
push (@array1, \@temp);
The reason I am assigning the strings and then putting them into an array is because they are in a loop and the values get updated in the loop (@array1 is not declared in the loop).
When I run my program, it only gives me a reference to an array rather than an actual 2D array. How can I get it to print out the content as a 2D array and not as a reference or flattened out to a 1D array?
I would like an output like [[blank1, blank2, blank3],....]
so i can access it like $array1[i][j]
CodePudding user response:
An array can only have scalars for elements. Thus this includes references, to arrays for example, what enables us to build complex data structures. See perldsc, Tom's Perl Data Structure Cookbook.
Elements of those ("second-level") arrays are accessed by dereferencing, so $array1[0]->[1]
is the second element of the array which reference is the first element of the top-level array (@array1
). Or, for convenience a simpler syntax is allowed as well: $array1[0][1]
.
If we want a list of all elements of a second-level array, then dereference it with @
, like:
my @l2 = @{ $array1[0] }; # or, using
my @l2 = $array1[0]->@*; # postfix dereferencing
The second line is a newer syntax called postfix dereferencing, stable as of v5.24. It avails us with the same logic for getting all elements as when we drill for a single one, by working left-to-right all the way. So ->@*
to get a list of elements for an arrayref,->%*
for a hashref (etc). See for instance a perl.com article and an Effective Perler article.
There is one thing to warn about when it comes to multidimensional structures built with references. There are two distinct ways to (create them)[https://perldoc.perl.org/perlreftut#Making-References), by using references to existing, named, variables
my @a1 = 5 .. 7;
my %h1 = ( a => 1, b => 2 );
my @tla1 = (\@a1, \%h1);
or by using anonymous ones, where arrayrefs are constructed by []
and hashrefs by {}
my @tla2 = ( [ 5..7 ], { a => 1, b => 2 } );
The difference is important to keep in mind. In the first case, the references to variables that the array carries can be used to change them -- if we change elements of @tla1
then we change the referred variables
$tla1[0][1] = 100; # now @a1 == 5, 100, 7
Also, changing variables with references in @tla1
is seen in the top-level array as well.
With anonymous array and hash in @tla
this isn't the case as @tla
accesses an independent set of the data, which cannot be accessed (and changed) in any other way. Both of these have their uses.