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};
string,href,string,href@doctorsto%doctors, then the LHS agrees with the intended RHS, and you have a hash of hashes.