I have two hashes which can contain the same keys. I am trying to merge the two hashes in such a way that if the key exists in both the hashes, I want to add the values in the respective hashes.
my %hash1= ();
$hash1{'apple'} = 10;
$hash1{'banana'} = 15;
$hash1{'kiwi'} = 20;
my %sourceHash = ();
$sourceHash{'apple'} = 12;
$sourceHash{'orange'} = 13;
$sourceHash{'banana'} = 5;
mergeHash(\%hash1, \%sourceHash);
sub mergeHash {
my $hash1 = shift;
my $hash2 = shift;
foreach my $key (keys %{$hash1})
{
if (exists $hash2->{$key}) {
${hash2}->{$key} = $hash1->{$key} + $hash2->{$key};
} else {
${hash2}->{$key} = $hash1->{$key};
}
}
}
I expect the result of hash1 to be
hash1{'apple'} = 22;
hash1{'orange'} = 13;
hash1{'banana'} = 20;
hash1{'kiwi'} = 20;
But I get an exception saying Can't modify constant item in scalar assignment. What am I doing wrong?
PFB the updated code with proper syntax and it is giving the desired output also:
my %hash1= ();
$hash1{'apple'} = 10;
$hash1{'banana'} = 15;
$hash1{'kiwi'} = 20;
my %sourceHash = ();
$sourceHash{'apple'} = 12;
$sourceHash{'orange'} = 13;
$sourceHash{'banana'} = 5;
mergeHash(\%hash1, \%sourceHash);
sub mergeHash {
my $param1 = shift;
my %hash1 = %$param1;
my $param2 = shift;
my %hash2 = %$param2;
foreach my $key (keys %hash1){
if(exists $hash2{$key}){
print "coming in here for $hash1->{$key} \n";
$hash2{$key} = $hash1{$key} + $hash2{$key};
}
else{
$hash2{$key} = $hash1{$key};
}
}
showHash(\%hash2);
}
sub showHash{
my $param = shift;
my %param_hash = %$param;
for my $fruit (keys %param_hash) {
print "The value of '$fruit' is $param_hash{$fruit}\n";
}
}
You say:
I expect the result of hash1 to be
hash1{'apple'} = 22;
hash1{'orange'} = 13;
hash1{'banana'} = 20;
hash1{'kiwi'} = 20;
But in your code, you iterate over the keys of $hash1
:
foreach my $key (keys %{$hash1})
And alter the contents of $hash2
:
if (exists $hash2->{$key}) {
${hash2}->{$key} = $hash1->{$key} + $hash2->{$key};
} else {
${hash2}->{$key} = $hash1->{$key};
}
So you shouldn't expect to see any changes in $hash1
, you are changing $hash2
.
I added this to your code:
use Data::Dumper;
And, after the call to mergeHash()
:
print Dumper \%hash1, \%sourceHash;
I got this output:
$VAR1 = {
'apple' => 10,
'kiwi' => 20,
'banana' => 15
};
$VAR2 = {
'orange' => 13,
'banana' => 20,
'kiwi' => 20,
'apple' => 22
};
So your code is doing what you wanted. It's just doing it to the other hash. There's nothing wrong with your code.