use List::Util qw(sum); # found in the CPAN
my $total = sum @hash{qw(foo bar baz)};
No need to even write a separate function... just open-code it as needed.
-- Randal L. Schwartz, Perl hacker | [reply] [d/l] |
sub _sum {
my $hash = shift;
my $total = 0;
$total += $_ for @$hash{ @_ };
return $total;
}
You can use a list of keys as indices into a hash. It's called a hash slice, and it's very very nice. | [reply] [d/l] |
Here. This is definitely NOT shorter, but it is more robust. And unless I'm clueless, using map in a situation like this creates a second array in RAM, which you are throwing away. While this may not be a problem, it does not promote efficient memory management.
#!/usr/bin/perl -w
use strict;
my %hash = ( foo => '123' , bar => '234',
batz => '345', bongo => '100' );
#send reference to hash, and list of keys to sum
print sum_hash( \%hash, 'foo', 'bar', 'batz' ) . "\n";
#send reference to hash, will sum all numeric values
print sum_hash( \%hash ) . "\n";
sub sum_hash {
my $t_hash = shift;
my $total;
if (@_) {
for (@_) {$total += $t_hash->{$_}; }
}
else {
for ( keys %$hashref ) { $total += $t_hash->{$_}; };
}
return $total;
}
| [reply] [d/l] |
For the else block, it's simpler to iterate over the values() rather than the keys. (Mind the name of the variable...)
else {
for (values %$t_hash) { $total += $_ }
# (use the statement modifier for if preferred)
}
The two blocks could also be combined into a single loop -- whether this is an improvement, I'm not sure. :)
sub sum_hash {
my $href = shift;
my $total = 0;
for ( @_ ? @{$href}{@_} : values %$href ) {
$total += $_;
}
return $total;
}
If @_ contains any elements, iterate over a hash slice using the contents of @_ as the keys; otherwise iterate over all the values in the hash. | [reply] [d/l] [select] |
Chipmunk, I love it. Your second method is especially Perlish.
| [reply] |
return unpack'%99d*',pack'd*',@hash{'foo', 'bar', 'baz'}; | [reply] [d/l] |
| [reply] |
#or if your numbers are large
use POSIX;
unpack"%@{[(DBL_MAX_EXP)-1]}d*",pack"d*",@hash{'foo', 'bar', 'baz'};
>;-} | [reply] [d/l] |