in reply to How to loop through hash of hashes and add the values based on condition?

What did you try?
  • Comment on Re: How to loop through hash of hashes and add the values based on condition?

Replies are listed 'Best First'.
Re^2: How to loop through hash of hashes and add the values based on condition?
by Sami_R (Sexton) on Jan 06, 2020 at 19:36 UTC
    Thanks.

    Attached the code which've tried ...

    for $name ( sort keys %{$VAR1} ) { for $calen ( sort keys %{ $VAR1{$name} } ) { for $value ( sort keys %{ $VAR1{$name}{$calen} } ) { if ( $VAR1{$name} ne ‘Sum’ ) { if ( ($VAR1{$name}{$calen} eq ‘days’) || ($VAR1{$name} +{$calen} eq ‘weeks’) ){ $day_week_total += $VAR1{$name}{$calen}{$value} if +($VAR1{$name}{$calen}{$value}); } elsif ( ($VAR1{$name}{$calen} eq ‘months’) ){ $month_total += $VAR1{$name}{$calen}{$value} if($V +AR1{$name}{$calen}{$value}); } } } } print “day_tot: $day_week_total — mon_tot: $month_total“;

      First, that's not your code, because there's a missing } and you have smartquotes instead of real quotes, so it wouldn't compile. I am otherwise ignoring those errors for now as probably an artifact of however you entered your post into the forum. As Fletch said, perldsc will help you; use warnings; use strict; will even help you find which variable you aren't referencing: Global symbol "%VAR1" requires explicit package name (did you forget to declare "my %VAR1"?) at C:\Users\....pl line 35.. Looking, your syntax $VAR1{$name} is looking up the $name key of the non-existent %VAR1 hash; you really want to look at the $name key of the $VAR1 hashref using the syntax $VAR1->{$name} -- and have multiple similar instances throughout. Also, Basic debugging checklist will help you debug your code; strict, warnings, and print statements easily found that problem. Try again, and if you're still having problems, post the full code (including example data and executable code in the same post), and explain the changes that you have made, why you made them.

      edit: that will only fix down to the $value loop, where you are trying to extract the $value from the keys of the non-existent subhash of $VAR1->{$name}{$calen}: that is not a hashref, but a scalar value, so you don't need to take the keys or loop over it. With that hint, I'll let you continue to figure out that portion, as well (there are more problems after that; I'm just stopping there for now)

        Hi PRYRT,

        Thank you so much for the direction and detailed explanation, its really helped to figure out the problem and fixed it, thanks again. I am novice to perl will catch up soon.

        use strict; use warnings; my $month_total = 0; my $day_week_total = 0; my $VAR1 = { 'Adam' => { 'days' => 22, 'weeks' => 5, 'total' => 22 }, 'Keas' => { 'total' => 114, 'test' => 2, 'weeks' => 8, 'days' => 107, 'months' => 5 }, 'Tim' => { 'total' => 4, 'weeks' => 5, 'days' => 3, 'months' => 1 }, 'Sum' => { 'total' => 440, 'days' => 365, 'months' => 9 } }; for my $name ( sort keys %{$VAR1} ) { for my $calen ( sort keys %{ $VAR1->{$name} } ) { if ( $name ne 'Sum' ) { if ( ($calen eq 'days') || ($calen eq 'weeks') ){ $day_week_total += $VAR1->{$name}->{$calen} if ($VAR1->{ +$name}->{$calen}); } elsif ( ($calen eq 'months') ){ $month_total += $VAR1->{$name}->{$calen} if($VAR1->{$nam +e}->{$calen}); } } } } print "\n day_total: $day_week_total —-- month_total: $month_total \n" +;

        Output: day_total: 150 —-- month_total: 6

      You can simplify all the dereferencing if you use a while loop with each rather than a for loop. With this method, you cannot sort the keys, but in your case, that is OK.
      use strict; use warnings; use Test::More tests => 2; my $month_total = 0; my $day_week_total = 0; my $VAR1 = { 'Adam' => { 'days' => 22, 'weeks' => 5, 'total' => 22 }, 'Keas' => { 'total' => 114, 'test' => 2, 'weeks' => 8, 'days' => 107, 'months' => 5 }, 'Tim' => { 'total' => 4, 'weeks' => 5, 'days' => 3, 'months' => 1 }, 'Sum' => { 'total' => 440, 'days' => 365, 'months' => 9 } }; while (my ($name, $hash) = each %$VAR1) { next if $name eq 'Sum'; if (exists $hash->{months}) { $month_total += $hash->{months}; } if (exists $hash->{days} and exists $hash->{weeks}) { $day_week_total += ($hash->{days} + $hash->{weeks}); } } ok($month_total == 6, 'month_total'); ok($day_week_total == 150, 'day_week_total'); OUTPUT: 1..2 ok 1 - month_total ok 2 - day_week_total
      Bill
        Hi Bill,

        Thank you so much for the support, code really helped!