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

Sorry to bother you guys (or girls) with this possibly easy question, but I think it is my duty as a newbie to vex you in any way possible. Now, on to my question. I have a multidimensional hash, the first dimension being the twelve months of the year, and the second dimension being the members in each month with their corresponding hours (i.e. $main{january}{johndoe} = 8). Is their an easy and fast way to add all the hours for a particular member? I've tried the obvious of adding $main{january}{johndoe}+$main{february}{johndoe} but that seems to take too long. Please help!

edited: Mon Nov 18 15:24:00 2002 by jeffa - changed title

Replies are listed 'Best First'.
Re: Iterating over hash elements
by BrowserUk (Patriarch) on Nov 17, 2002 at 22:01 UTC

    my $totalHours = 0; $totalHours += $main{$month}{johndoe}for my $month (keys %main);

    Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
    Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
    Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
    Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

Re: Summing values of subkey in a HoH
by Aristotle (Chancellor) on Nov 18, 2002 at 00:09 UTC
    Why does everyone's code build a list of keys when they don't use them for anything but accessing the values?
    my $total; $total += $_->{$member} for values %main;
    (At this this point it's obvious that %main needs a better name.)

    Makeshifts last the longest.

Re: Iterating over hash elements
by Zaxo (Archbishop) on Nov 17, 2002 at 22:11 UTC

    Here you go:

    my ($member,$total) = 'johndoe'; $total += $main{$_}{$member} for keys %main;
    If you want to do that for each member, it would be convenient to define a %total hash with member names as keys. It could go like this:
    my %total; for my $month (keys %main) { $total{$_} += $main{$month}{$_} for keys %{$main{$month}}; }
    I think %main could use a better name.

    After Compline,
    Zaxo

Re: HoH Issue(AKA Iterating over hash elements)
by Enlil (Parson) on Nov 17, 2002 at 22:04 UTC
    After perusing through the perldsc, you might come up with something like the following code (untested):
    my $johndoe_hours = 0; foreach my $month ( keys %main } { $johndoe_hours += $johndoe_hours + $main{$month}{johndoe}; }

    my $johndoe_hours = 0; foreach my $month ( keys %main } { $johndoe_hours += $main{$month}{johndoe}; }
    If you want to get rid of the error message when {johndoe} does not exist in the hash $main{$month} (that is assuming you are using warnings), you might want to do something like the following instead:
    my $johndoe_hours = 0; foreach my $month ( keys %main } { if ( exists $main{$month}{johndoe} ) { $johndoe_hours += $johndoe_hours + $main{$month}{johndoe}; } }

    my $johndoe_hours = 0; foreach my $month ( keys %main } { if ( exists $main{$month}{johndoe} ) { $johndoe_hours += $main{$month}{johndoe}; } }
    update: Fixed code from doubling johndoe's hours.

    -enlil

Re: Iterating over hash elements
by pg (Canon) on Nov 18, 2002 at 07:54 UTC
    It makes more sense to use HoA in this case. Let hash key be the person's name, and value be the ref to an array, which has 12 elements, and each array element contains the hours for that month that person.