user1987607
user1987607

Reputation: 2157

perl - access elements in hash of arrays of arrays

I have the following hash of arrrays of arrays in perl

$VAR1 = {
      'A' => [
                   [
                     '1',
                     'PRESENT_1',
                     'ABSENT_2',
                   ],
                   [
                     '2',
                     'PRESENT_1',
                     'ABSENT_2',
                   ]
                 ],
      'B' => [
                  [
                    '5',
                    'PRESENT_1',
                    'ABSENT_2',
                  ],
                  [
                    '6',
                    'PRESENT_1',
                    'ABSENT_2',
                  ],
                  [
                    '7',
                    'ABSENT_1',
                    'PRESENT_2',
                  ]
                ]
    };

I want to access the first element from each small array and print it to the console.

So the output should look like this

EL 1
EL 2
EL 5
EL 6
EL 7

I'm having difficulties with looping through the arrays and dereferencing. I've started like this, but that's clearly not the correct way

my %hash = %{ $VAR1 };
for my $key (sort keys %hash) {
   for my $arr1 (@{ $hash{$key} }){
       for my $arr2 (@{ $arr1}) {
            print "EL ", @{ $arr2 }[0], "\n";
       }
    }
}

Upvotes: 2

Views: 115

Answers (2)

zdim
zdim

Reputation: 66883

It's close.

Iterate over elements (this also prints out the first one, separately)

my %hash = %{ $hashref };
for my $key (sort keys %hash) {
   for my $arrayref (@{ $hash{$key} }) {
       say "First element: ", $arrayref->[0];
       for my $elem (@$arrayref) {
            say "element: $elem";
       }
    }
}

(need to say use feature qw(say); somewhere on top, for feature say)

So for the first element alone -- if that's indeed all you need -- there is no need for the inner loop at all


Then, just for an exercise, for the first element alone one can also do

say $_->[0] for map { @{$hash{$_}} } sort keys %hash;

And since we're manipulating lists out of arrayrefs let's mention postfix dereferencing, available since v5.20 and stable in v5.24

use feature qw(postderef);

say $_->[0] for map { $hash{$_}->@* } sort keys %hash;

It doesn't buy us much here but then again here it's clear what it does.

Upvotes: 2

vkk05
vkk05

Reputation: 3222

Try this:

use strict; use warnings;
use Data::Dumper;

my $VAR1 = {
      'A' => [
                   [
                     '1',
                     'PRESENT_1',
                     'ABSENT_2',
                   ],
                   [
                     '2',
                     'PRESENT_1',
                     'ABSENT_2',
                   ]
                 ],
      'B' => [
                  [
                    '5',
                    'PRESENT_1',
                    'ABSENT_2',
                  ],
                  [
                    '6',
                    'PRESENT_1',
                    'ABSENT_2',
                  ],
                  [
                    '7',
                    'ABSENT_1',
                    'PRESENT_2',
                  ]
                ]
    };
    
my %hash = %{ $VAR1 };
print Dumper(\%hash);

foreach my $key (sort keys %hash) {
    foreach my $inner (@{$hash{$key}}){
        print "EL ".@$inner[0]."\n";
    }
}

Output:

EL 1
EL 2
EL 5
EL 6
EL 7

Upvotes: 2

Related Questions