Reputation: 542
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]
Upvotes: 1
Views: 83
Reputation: 66964
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 whose 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
Or, to get just a few elements of the array, but in one scoop -- a slice
my @l2_slice = @{$array1[0]}[1..2]; # or
my @l2_slice = $array1[0]->@[1..2]; # postfix reference slice
what returns the list with the second and third elements of the same second-level array.
The second lines are of a newer syntax called postfix dereferencing, stable as of v5.24. It avails us with the same logic for getting elements as when we drill for a single one, by working left-to-right all the way. So ->@*
to get a list of all elements for an arrayref,->%*
for a hashref (etc). See for instance a perl.com article and an Effective Perler article.
There is a thing to warn about when it comes to multidimensional structures built with references. There are two distinct ways to create them: 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 those variables -- if we change elements of @tla1
then we really change the referred variables
$tla1[0][1] = 100; # now @a1 == 5, 100, 7
Also, changing variables with references in @tla1
is seen via the top-level array as well.
With anonymous arrays and hashes in @tla
this isn't the case as elements (references) of @tla
access independent data, which cannot be accessed (and changed) in any other way.
Both of these ways to build complex data structures have their uses.
Upvotes: 5