0

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'};
10
  • That's not an array of hashes, but a hash of hashes. Commented Dec 3, 2013 at 17:53
  • 4
    It's neither, actually Commented Dec 3, 2013 at 17:54
  • array of string,href,string,href Commented Dec 3, 2013 at 17:56
  • If you change @doctors to %doctors, then the LHS agrees with the intended RHS, and you have a hash of hashes. Commented Dec 3, 2013 at 17:57
  • 2
    That is an array where the first and third elements are strings and the second and fourth are hashrefs. It is pretty clear :D Commented Dec 3, 2013 at 18:02

4 Answers 4

3

Arrays don't have keys,

my @doctors = (
         {
          'name'            => 'abcd',
          'specialization'  => 'xyz',
          'city'            => 'pqr'
          },
         {
          'name'            => 'efgh',
          'specialization' => 'mno',
          'city'            => 'stu'
          }
);
print $doctors[0]{'name'};
Sign up to request clarification or add additional context in comments.

Comments

3

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};

Comments

2

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};

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.