SwiftMango
SwiftMango

Reputation: 15294

How to get sub array?

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?

Upvotes: 5

Views: 5964

Answers (4)

Dondi Michael Stroma
Dondi Michael Stroma

Reputation: 4800

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

Upvotes: 6

Jared
Jared

Reputation: 26397

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'
        ];

Upvotes: 6

David
David

Reputation: 6571

I think you're after an array of arrays. So, you need to create an array of array references by using square brackets, like this:

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

Then you can print the second array as follows:

print @{$a[1]};

Which will give you the output you were expecting: testhello

Upvotes: 3

m0skit0
m0skit0

Reputation: 25873

It's just a matter of wrong syntax:

print $a[1]

Upvotes: -4

Related Questions