Reputation: 4025
i have a problem where I need to have an array as a value in an associative array.
Go through the code below. Here I am trying to loop the files in a directory and it is more likely that more than 1 file can have the same ctrno
. So, I would like to see what are all the files having the same ctrno
. The code below gives error at "$ctrno_hash[$ctrno] = @arr;
" in the else condition. The same case would be for if condition as well.
Am I following the right approach or could it be done differently?
sub loop_through_files
{
$file = "@_";
open(INPFILE, "$file") or die $!;
#print "$file:$ctrno\n";
while (<INPFILE>)
{
$line .= $_;
}
if ($line =~ /$ctrno/ )
{
print "found\n";
if ( exists $ctrno_hash[$ctrno])
{
local @arr = $ctrno_hash[$ctrno];
push (@arr, $file);
$ctrno_hash[$ctrno] = @arr;
}
else
{
local @arr;
push(@arr, $file);
$ctrno_hash[$ctrno] = @arr;
}
}
}
Upvotes: 1
Views: 1453
Reputation: 40603
I believe you want something like
$ctrno_hash[$ctrno] = \@arr;
This will turn the array @arr
into a array reference
.
You then refer to the previously pushed array reference with
@{$ctrno_hash[$ctrno]}
That is, if $array_ref
is an array reference, the construct @{ $array_ref }
returns the array to which the array reference points.
Now, the construct $ctrno_hash[$ctrno]
is not really a hash, but an ordinary array. In order to truly make it a hash, you need the curly brackets instead of the square brackets:
@{$ctrno_hash{$ctrno} } = \@arr;
And similarly, you later refer to the array with
@{$ctrno_hash{$ctrno} }
Now, having said that, you can entirly forgo the if ... exists
construct:
if ($line =~ /$ctrno/ )
{
print "found\n";
push @{$ctrno_hash{$ctrno}}, $file
}
Upvotes: 5