ImDrPatil
ImDrPatil

Reputation: 197

How to access array of hashes?

Hi i have an array of hashes as below, i want access hash element/elements. Say suppose i want to print doct1's name, i am not getting right result please help me how do i print that?

@doctors = (
    'doct1' => {
          'name'            => 'abcd',
          'specialization'  => 'xyz',
          'city'            => 'pqr'
          },
    'doct2' => {
          'name'            => 'efgh',
          'specialization' => 'mno',
          'city'            => 'stu'
          }
);
print $doctors[0]{'name'};

Upvotes: 0

Views: 96

Answers (4)

ikegami
ikegami

Reputation: 385565

You don't have an AoH. You have an array containing both strings and references to hashes. This is a very poor data structure. It's messy and inefficient to locate the correct doctor.

my $i = 0;
$i += 2 while $i<@doctors && $doctors[$i] ne 'doct1';
die "Not found" if $i > @doctors;
say $doctors[$i+1]{name};

If you had an AoH as you say, it you look something like this:

my @doctors = (
   {
      id             => 'doct1',
      name           => 'abcd',
      specialization => 'xyz',
      city           => 'pqr',
   },
   {
      id             => 'doct2',
      name           => 'efgh',
      specialization => 'mno',
      city           => 'stu',
   },
);

That would be better.

my ($doctor) = grep { $_->{id} eq 'doct1' } @doctors
   or die "Not found";
say $doctor->{name};

It's also possible that doct1 and doct2 are meaningless, and that you'd be happy using 0 and 1 instead. If so,

die "Not found" if @doctors < 0;
say $doctors[0]{name};

If doct1 and doct2 aren't meaningless, then the cleanest and most efficient solution would be to use an HoH.

my %doctors = (
   doct1 => {
      name           => 'abcd',
      specialization => 'xyz',
      city           => 'pqr',
   },
   doct2 => {
      name           => 'efgh',
      specialization => 'mno',
      city           => 'stu',
   },
);

The code would then be the simple:

my $doctor = $doctors{doct1}
   or die "Not found";
say $doctor->{name};

Upvotes: 3

leonbloy
leonbloy

Reputation: 75896

The right hand declaration is not very consistent (in intention) with the assignment to an array. You'd probably want to assign it to a hash instead:

%doctors = (
    'doct1' => {
          'name'            => 'abcd',
          'specialization'  => 'xyz',
          'city'            => 'pqr'
          },
    'doct2' => {
          'name'            => 'efgh',
          'specialization' => 'mno',
          'city'            => 'stu'
          }
);

print $doctors{'doct1'}->{'name'};

Either this or, mpapec's answer.

Upvotes: 0

Hunter McMillen
Hunter McMillen

Reputation: 61515

This is a situation where using Data::Dumper is essential, what you actually have is an array of two strings and two hashrefs. If you were to print it out with Data::Dumper you would see this:

use Data::Dumper;
print Dumper \@doctors;
[
   'doct1',
   {
     'city' => 'pqr',
     'specialization' => 'xyz',
     'name' => 'abcd'
   },
   'doct2',
   {
     'city' => 'stu',
     'specialization' => 'mno',
     'name' => 'efgh'
   }
];

Each hashref has all the data that represents a doctor, the additional key at the front doesn't make any sense. Remove those keys and you will have a structure like this:

@doctors = (
          {
           'name'            => 'abcd',
           'specialization'  => 'xyz',
           'city'            => 'pqr'
          },
          {
           'name'            => 'efgh',
           'specialization'  => 'mno',
           'city'            => 'stu'
          }
);

and now you can access the hash attributes like you would expect:

print $doctors[0]{name};

Upvotes: 2

mpapec
mpapec

Reputation: 50637

Arrays don't have keys,

my @doctors = (
         {
          'name'            => 'abcd',
          'specialization'  => 'xyz',
          'city'            => 'pqr'
          },
         {
          'name'            => 'efgh',
          'specialization' => 'mno',
          'city'            => 'stu'
          }
);
print $doctors[0]{'name'};

Upvotes: 3

Related Questions