Reputation: 1031
Hi I have a hash where the key is a 3digit code and value is number of elements under that code. I want to sum the 3digit code and multiply with the number of elements, then finally add them up. Example:
000 23
012 42
222 34
[(0+0+0)*23]+[(0+1+2)*42]+[(2+2+2)*34]=0+126+204=330
so i tried
foreach my $key (sort keys %hash ){
@arrSum=split(//, $key);
foreach $i (@arrSum){
$sum+=$i;
$value=$sum*$hash{$key};
}
}
It does not work. It actually has to consider each line, instead it sums up all the 3digit code at once. Need some help.
Upvotes: 2
Views: 6000
Reputation: 3967
I made a small change in your code, and I got the right value:
#!/usr/bin/perl
use strict;
use warnings;
my %hash = (
"000" => 23,
"012" => 42,
"222" => 34,
);
my $value = 0;
for my $key (sort keys %hash )
{
my $sum = 0;
my @arrSum = split(//, $key);
for my $i (@arrSum)
{
$sum += $i;
}
$value += $sum * $hash{$key};
}
print "$value\n";
Upvotes: 4
Reputation: 385847
(a+b+c)*d = (a*d)+(b*d)+(c*d), so you could do
my $value;
for my $key (keys %hash) {
for my $digit (split(//, $key)) {
$value += $digit * $hash{$key};
}
}
But it looks like you were trying for:
my $value;
for my $key (keys %hash) {
my $sum;
$sum += $_ for split(//, $key);
$value += $sum * $hash{$key};
}
More or less the same:
use List::Util qw( sum );
my $value;
for my $key (keys %hash) {
$value += sum(split(//, $key)) * $hash{$key};
}
Upvotes: 1
Reputation: 118128
This problem seems tailor-made for each:
#!/usr/bin/perl
use warnings; use strict;
use List::Util qw( sum );
my %hash = (
"000" => 23,
"012" => 42,
"222" => 34,
);
my $total;
while ( my ($key, $val) = each %hash ) {
$total += sum(split //, $key) * $val;
}
print "$total\n";
Upvotes: 1
Reputation: 9697
Here is more functional approach to the problem, it also uses sum
from List::Util:
use List::Util qw(sum);
my %hash = qw(
000 23
012 42
222 34
);
print sum(map { sum(split //) * $hash{$_} } keys %hash); # 330
Upvotes: 18