mamesaye
mamesaye

Reputation: 2153

Find the size of an array of hash in Perl

How do you get the size of the following array of hashes?

I thought this would do it, but it did not work...

print Dumper scalar $item->{'detail'};
$VAR1 = [
    { 'content' => undef, 'name' => 'entree',  'url_name' => 'entree' },
    { 'content' => undef, 'name' => 'dessert', 'url_name' => 'desert' },
    { 'content' => undef, 'name' => 'drink',   'url_name' => 'drink'  }
];

Or how can I print all the url_name (entree, desert, drink) in the array of hashes without knowing the size?

Upvotes: 1

Views: 5579

Answers (2)

perreal
perreal

Reputation: 97948

You have an array reference. To get the size of the referenced array, first dereference the reference:

print scalar @{$item->{'detail'}};

And to list the URLs:

my $v = [
      { 'content' => undef, 'name' => 'entree', 'url_name' => 'entree' },
      { 'content' => undef, 'name' => 'dessert', 'url_name' => 'desert' },
      { 'content' => undef, 'name' => 'drink', 'url_name' => 'drink' }
];   # or $v = $item->{'detail'};

foreach my $h (@$v) {
  print $h->{url_name}, "\n";
}

Upvotes: 8

TLP
TLP

Reputation: 67908

I'm not sure why you think you need the array size in order to print the url_name values. Nonetheless, here's how it works.

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

my $v = [   # note that this is a scalar value
    { 'content' => undef, 'name' => 'entree', 'url_name' => 'entree' },
    { 'content' => undef, 'name' => 'dessert', 'url_name' => 'desert' }, 
    { 'content' => undef, 'name' => 'drink', 'url_name' => 'drink' } 
];  
my $item = { detail => $v };        # recreate your structure $item->{detail}
my $size = @$v;                     # this is how its done with $v
my $size2 = @{ $item->{detail} };   # and with your original structure
my @x = map $_->{url_name}, @$v;    # extract url_name values
print Dumper \@x;

As you see, $item->{detail} and $v are identical. When you feed this scalar value directly (through the scalar function, which does nothing in this case) to Dumper, you get the printed value seen in $v above. All that scalar does is change the context used with print and enforce a scalar context rather than list context. We can do the same thing by using scalar assignment ($size and $size2).

When using the original structure, you need to use the @{ } brackets to clarify for perl that what is inside them is an array ref.

As you see, extracting the values is easily done with a map statement. It acts as a loop, iterating over all the values in @$v (or @{ $item->{detail} }), returning for each value the statement $_->{url_name}.

Upvotes: 1

Related Questions