more useful options PerlMonks

### calculating array average in HoA

by benben (Novice)
 on Apr 21, 2012 at 20:32 UTC Need Help??

benben has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have a hash of arrays like this:

```%HoA = (
A => [2.34, 4.12, 5.32],
B => [1.42, 8.15],
C => [8.42, 0.23, 0.45, 6.43],
###...and so on
);

I want to calculate average of each array and display the result like:

```A   3.93
B   4.79
...etc.

I'm not sure how to do this though... that's what I've written so far: Any suggetions?

```my \$average;
foreach my \$key (keys %HoA) {
foreach my \$value (values %HoA) {
my @Array = \$value;
\$average = average (\@Array);
}
print \$key, "\t", \$average, "\n",
}

sub average {
my (\$array_ref) = @_;
my \$sum;
my \$count = scalar @\$array_ref;
foreach (@\$array_ref) {
\$sum += \$_;
}
my \$av =  \$sum/\$count;
return \$av;
}

Replies are listed 'Best First'.
Re: calculating array average in HoA
by choroba (Cardinal) on Apr 21, 2012 at 20:38 UTC
You are almost there. Just do not loop over values and keys:
```use warnings;
use strict;

my %HoA = (
A => [2.34, 4.12, 5.32],
B => [1.42, 8.15],
C => [8.42, 0.23, 0.45, 6.43],
);

foreach my \$key (keys %HoA) {
print \$key, "\t", average(\$HoA{\$key}), "\n";
}

sub average {
my \$array_ref = shift;
my \$sum;
foreach (@\$array_ref) {
\$sum += \$_;
}
my \$av = \$sum / @\$array_ref;
return \$av;
}
Re: calculating array average in HoA
by aaron_baugher (Curate) on Apr 21, 2012 at 21:28 UTC

```foreach my \$key (keys %HoA) {
foreach my \$value (values %HoA) {
my @Array = \$value;

For each key in your hash, you're looping through all the values in your hash. You want to loop through the keys, and for each one, average the values in the particular array that it points to. Also, in the last line above, assigning a scalar to an array will simply make the scalar the first element of the array. Since your scalar is an array reference, you want to dereference it to get the array it points to. Which gives you these lines instead of the above:

```for my \$key (keys %HoA){    # loop through the keys
my \$value = \$HoA{\$key}; # get the array ref for this key
my @Array = @{\$value};  # dereference it to get the array

You can shorten that up and eliminate a step or two once you understand it, but that's the process broken down into small steps.

One last thing: no need to instantiate \$average outside your loop, since you only use it inside the loop. Better to instantiate it inside, in the narrowest possible context.

Aaron B.
My Woefully Neglected Blog, where I occasionally mention Perl.

Re: calculating array average in HoA
by jwkrahn (Monsignor) on Apr 22, 2012 at 03:15 UTC
```\$ perl -e'
use List::Util q/sum/;
my %HoA = (
A => [ 2.34, 4.12, 5.32 ],
B => [ 1.42, 8.15 ],
C => [ 8.42, 0.23, 0.45, 6.43 ],
);
for my \$key ( keys %HoA ) {
printf "%s\t%.2f\n", \$key, sum( @{ \$HoA{ \$key } } ) / @{ \$HoA{ \$ke
+y } };
}
'
A       3.93
C       3.88
B       4.79
Re: calculating array average in HoA
by JavaFan (Canon) on Apr 21, 2012 at 20:52 UTC
```local \$" = "+";
printf "%s  %.2f\n", \$_, (eval "@{\$HoA{\$_}}") / @{\$HoA{\$_}} for keys %
+HoA;

Just out of curiosity, how did the OP err in their question to justify such an obfuscated, likely unhelpful response?

Why do you think the OP had to err to get JavaFans reply? Also why do you think it is obfuscated and unhelpful?

I say the line local \$" = "+"; pretty much explained the rest of the code, and to me at least it was faster to understand JavaFans code than the first answer even though my solution would have been closer to that first answer.

JavaFan, you have my apology if your reply to the OP wasn't meant to be sarcastic. We've just seen a fair amount of that lately, even on posts where the SoPW lay out relatively decent questions.

Normally I'd discuss such an issue if I have one with the author of a post, especially if the tone of the reply is ambiguous in my mind, like this one is now.

I spoke before I thought in this case, and alcohol wasn't even involved ;)

Re: calculating array average in HoA
by Kenosis (Priest) on Apr 21, 2012 at 21:28 UTC

Brilliant solution, JavaFan! A sort before keys would 'prettify' the output.

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://966408]
Approved by Happy-the-monk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2023-12-02 06:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
What's your preferred 'use VERSION' for new CPAN modules in 2023?

Results (13 votes). Check out past polls.

Notices?