Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get sub array?

Tags:

perl

I have the code below:

@a = ((1,2,3),("test","hello"));
print @a[1]

I was expecting it to print

testhello

But it gives me 2.

Sorry for the newbie question (Perl is a bit unnatural to me) but why does it happen and how can I get the result I want?

like image 583
SwiftMango Avatar asked Dec 20 '22 07:12

SwiftMango


2 Answers

The way Perl constructs @a is such that it is equivalent to your writing,

@a = (1,2,3,"test","hello");

And that is why when you ask for the value at index 1 by writing @a[1] (really should be $a[1]), you get 2. To demonstrate this, if you were to do the following,

use strict;
use warnings;
my @a = ((1,2,3), ("test","hello"));
my @b = (1,2,3,"test","hello");
print "@a\n";
print "@b\n";

Both print the same line,

1 2 3 test hello
1 2 3 test hello

What you want is to create anonymous arrays within your array - something like this,

my @c = ([1,2,3], ["test","hello"]);

Then if you write the following,

use Data::Dumper;
print Dumper $c[1];

You will see this printed,

$VAR1 = [
          'test',
          'hello'
        ];
like image 94
Jared Avatar answered Dec 22 '22 21:12

Jared


Perl lists are one-dimensional only, which means (1,2,(3,4)) is automatically flattened to (1,2,3,4). If you want a multidimensional array, you must use references for any dimension beyond the first (which are stored in scalars).

You can get any anonymous array reference with bracket notation [1,2,3,4] or reference an existing array with a backslash my $ref = \@somearray.

So a construct such as my $aref = [1,2,[3,4]] is an array reference in which the first element of the referenced array is 1, the second element is 2, and the third element is another array reference.

(I find when working with multidimensional arrays, that it's less confusing just to use references even for the first dimension, but my @array = (1,2,[3,4]) is fine too.)

By the way, when you stringify a perl reference, you get some gibberish indicating the type of reference and the memory location, like "ARRAY(0x7f977b02ac58)".

Dereference an array reference to an array with @, or get a specific element of the reference with ->.

Example:

my $ref = ['A','B',['C','D']];
print $ref;                   # prints ARRAY(0x001)
print join ',', @{$ref};      # prints A,B,ARRAY(0x002)
print join ',', @$ref;        # prints A,B,ARRAY(0x002) (shortcut for above)
print $ref->[0];              # prints A
print $ref->[1];              # prints B
print $ref->[2];              # prints ARRAY(0x002)
print $ref->[2]->[0];         # prints C
print $ref->[2][0];           # prints C (shortcut for above)
print $ref->[2][1]            # prints D
print join ',', @{$ref->[2]}; # prints C,D
like image 34
Dondi Michael Stroma Avatar answered Dec 22 '22 19:12

Dondi Michael Stroma