Dan Klose wrote:
> Hello Everyone.
> 
> I have the following code:
> 
> 
> ### CODE BLOCK ###
> 
> my %hash_of_arrays2;
>

Have you considered a hash of hashes? For me, given the sample below, I
would prefer it, but obviously I haven't seen your whole script.

> for (keys %hash_of_arrays) {
>   my @array_of_data = exists($hash_of_arrays{$_})
>     [EMAIL PROTECTED]
>       :();

I don't think the above is doing what you anticipate. 'exists' just
tests whether there is a key/value pair given the key. But since you are
iterating over the keys of the hash the test must always be true. If
there is no value, then your initialization will be the same as ()
anyways. So basically you can drop the above completely, or a better
check would be to test the number of elements (make sure you have an
array ref first if you are worried about it).

perldoc -f exists

> 
>   my $mean = mean([EMAIL PROTECTED]); #GET MEAN
>   my $std_dev = dev([EMAIL PROTECTED]); #GET STANDARD DEV
> 

Given that the above two functions take an array reference there is no
reason to dereference the array reference first, just to pass a
reference. You are using twice the memory to do so when the references
should allow you to save on memory that Perl would automatically duplicate.

>   push @{$hash_of_arrays2{$_}}, $mean;
>   push @{$hash_of_arrays2{$_}}, $std_dev;

This gets back to my question of the hash of hashes. Rather than
stuffing the mean and std_dev into indexes 0 and 1, why not just put
them in named indexes.

$hash_of_hashes->{$_}->{'mean'} = $mean;
$hash_of_hashes->{$_}->{'std_dev'} = $std_dev;

> }
> 
> for (sort {$hash_of_arrays2{$a}[0] <=> $hash_of_arrays2{$b}[0]} 
>      keys %hash_of_arrays2) {
> 
>   print "$_, $hash_of_arrays2{$_}[0], $hash_of_arrays2{$_}[1]\n";
> }
> 
> ### END OF CODE ###
> 
> If anyone has the time could you please show me ways of shortening this
> code e.g. eliminating the second for block (integration into the
> previous block) and any other tips / tricks.
> 

The problem is that to do a sort you have to know all of the values that
you are sorting on before you can start, which means you can't print the
output in a sorted manner in the first loop, so there really is no way
to combine the two. The best you could hope for would be to populate an
array in sorted order in the first loop and then just print the result
in the second, but your sorting routine would very likely be less
efficient than Perl's built-in one.

> There are no other people here that code perl and so I get no
> advice/feedback on how to improve my scripts.
>

You have come to the right place then. I know that feeling, it stinks.

> Thanks in advance.
> 
> Dan.

http://danconia.org

-- UNTESTED --
my %hash_of_calculations;
for my $key (keys %hash_of_arrays) {
  if (ref $hash_of_arrays->{$key} eq 'ARRAY' and
@{$hash_of_arrays->{$key}}) {
    # data to process
    @{$hash_of_calculations->{$key}}{'mean','std_dev'} =
(mean($hash_of_arrays->{$key}), dev($hash_of_arrays->{$key}));
  }
  else {
     # no data to process
     @{$hash_of_calculations->{$key}}{'mean','std_dev'} = ();
  }
}
for my $key (sort { $hash_of_calculations->{$a}->{'mean'} <=>
$hash_of_calculations->{$b}->{'mean'} } keys %hash_of_calculations) {
  print "Key: $key\n";
  print "Mean: $hash_of_calculations->{$key}->{'mean'}\n";
  print "Std Dev: $hash_of_calculations->{$key}->{'std_dev'}\n";
}

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to