views:

205

answers:

2

I am writing a Perl script to do some mathematical operations on a hash. This hash contains the values as given in the sample below. I have written the code below. If I execute this code for an array value separately without using a foreach loop, the output is fine. But if I run this using a foreach loop on the array values, the sum for values in A are good, but from B the output add the previous values.

Hash Sample:

$VAR1 = 'A';
$VAR2 = {
    '"x"' => [values],
    '"y"' => [values],
    and so on...
$VAR3 = 'B';
$VAR4 = {
     '"x"' => [values],
    '"y"' => [values],
    and so on...
$VARn....

Code:

#!/usr/bin/perl -w
use strict;
use List::Util qw(sum);

my @data;
my @count;
my $total;

my @array = ("A", "B", "C", "D");

foreach my $v (@array) {

        my %table = getV($v); #getV is a subroutine returing a hash. 
        for my $h (sort keys %table) {
                  for my $et (sort keys %{ $table{$h} } ) {
     for $ec ($table{$h}{$et}) {
                            push @data, $ec;
                            @count = map { sum(@{$_}) } @data;
                            $total = sum(@count);
                        }
           }
print "sum of $v is  $total\n";
}

I think the issue is with this line. It is storing all the previous values and hence adding all the values in next foreach loop.

push @data, $ec;

So, here I have two issues:

1) How can I refresh the array (@data) in each foreach loop iteration?

2) How can I add the values in the array ref ($ec) and store them in an array? Because when I use the following code:

for $ec ($table{$h}{$et}) {
    @count = map { sum(@{$_}) } @$ec;
    $total = sum(@count);
}

The output gives me the same values for @count and $total.

Please provide me with suggestions.

+4  A: 

If I understand you correctly, just a small change in your code. Make an empty array (@data) at the beginning of for loop. Hope this helps.

        for my $h (sort keys %table) {
                  my @data;
Space
In fact, all you need to say is `my @data;` inside the loop, and it will be a new `@data` each time through.
friedo
The `= ()` in `my @data = ();` is pointless. When you create an array with `my` it starts out empty. Assigning an empty list to it does nothing put was your and Perl's time.
Chas. Owens
A: 

1) Declare the @data array at the top of the loop body where you want to start with a fresh, empty array. Or maybe you mean to be saying @data = @$ec, not push @data, $ec?

2) To add the values in the array referred to by $ec, you would just say sum(@$ec); no map required.

It's not completely clear what your data structure is or what you are trying to do with it. It would help to see what a sample %table looks like and what results you expect from it.

ysth