How to create a multidimensional array in perl?

I created a multidimensional array as follows:

#!/usr/bin/perl use warnings; use strict; my @a1 = (1,2); my @a2 = (@a1,3); 

But it turns out that I still have a one-dimensional array ...

What is the correct way in perl?

+4
source share
6 answers

You get a one-dimensional array because the @a1 array expands inside parens. So, assuming:

 my @a1 = (1,2); my @a2 = (@a1,3); 

Then your second statement is equivalent to my @a2 = (1,2,3); .

When creating a multidimensional array, you have several options:

  • Direct assignment of each value
  • Selecting an existing array
  • Link insertion

The first option is basically $array[0][0] = 1; Not very exciting.

The second does this: my @a2 = (\@a1, 3); Note that this makes a namespace reference for the @a1 array, so if you change @a1 later, the values ​​inside @a2 will also change. Not always a recommended option.

A variant of the second option does the following: my @a2 = ([1,2], 3); The brackets will create an anonymous array that does not have a namespace, only a memory address and will exist only inside @a2 .

The third option, a little more obscure, does this: my $a1 = [1,2]; my @a2 = ($a1, 3); my $a1 = [1,2]; my @a2 = ($a1, 3); It will do the same as 2, only the array reference is already in the scalar variable called $a1 .

Note the difference between () and [] when assigning to arrays. The brackets [] create an anonymous array that returns a reference to the array as a scalar value (for example, which can be held by $a1 or $a2[0] ).

Parens, on the other hand, do nothing at all but change the priority of the statements.

Consider this piece of code:

 my @a2 = 1, 2, 3; print "@a2"; 

1 open. If you use warnings , you will also receive a warning, for example: Useless use of a constant in void context . This mainly happens:

 my @a2 = 1; 2, 3; 

Because commas ( , ) have lower priority than equalsign = . (See "Operator Priority and Associativity" in perldoc perlop )

What parens does simply negates the default priority = and,, and group 1,2,3 together in the list, which is then passed to @a2 .

So, in short, the brackets [] have some magic in them: they create anonymous arrays. Parens () will simply change the priority, as in math.

You can read a lot in the documentation. Someone here once showed me a very good dereferencing link, but I don’t remember what it is. At perldoc perlreftut you will find a basic reference guide. And in perldoc perldsc you will find documentation on data structures (thanks to Oesor for reminding me).

+9
source

I would suggest working through perlreftut , perldsc and perllol , preferably on the same day and preferably using Data::Dumper to print data structures.

The textbooks complement each other, and I think they will work together more effectively. The visualization of data structures has helped me believe a lot that they really work (seriously) and see my mistakes.

+6
source

Arrays contain scalars, so you need to add a link.

 my @a1 = (1,2); my @a2 = (\@a1, ,3); 

You need to read http://perldoc.perl.org/perldsc.html .

+4
source

The most important thing to understand about all data structures in Perl - including multidimensional arrays - is that they can do differently, Perl @ARRAY s and % HASH are all internally one-dimensional. They can only contain scalar values ​​(meaning a string, number, or link). They cannot directly contain other arrays or hashes, but instead contain links to other arrays or hashes.

Now, since the top level contains only links, if you try to print your array using the simple print () function, you will get something that does not look very pretty, for example:

  @AoA = ( [2, 3], [4, 5, 7], [0] ); print $AoA[1][2]; 7 print @AoA; ARRAY(0x83c38)ARRAY(0x8b194)ARRAY(0x8b1d0) 

This is because Perl does not (ever) implicitly dereference your variables. If you want to get the information referenced by a link, you need to do it yourself using either prefix input indicators, for example ${$blah} , @{$blah} , @{$blah[$i]} , or postfix pointer arrows eg $a->[3] , $h->{fred} or even $ob->method()->[3]

Source: perldoc


Now to your question. Here is your code:

 my @a1 = (1,2); my @a2 = (@a1,3); 

Note that arrays contain scalar values. Thus, you must use the link, and you can add the link using the \ keyword in front of the name of the array to be referenced.

Like this:

 my @a2 = (\@a1, ,3); 
+2
source

Internal arrays must be scalar links in the external:

 my @a2 = (\@a1,3); # first element is a reference to a1 print ${$a2[0]}[1]; # print second element of inner array 
+1
source

This is a simple example of a 2D array as ref

 my $AoA=undef; for(my $i=0;$i<3;$i++) { for(my $j=0;$j<3;$j++) { $AoA->[$i]->[$j] = rand(); #assign some value } } 
0
source

All Articles