Hey, that's was pretty slick. crazysniffable, if you're not sure what's going on, here's the scoop:
The map operator takes an array and loops over each element. In this case, the array is the keys of %hash. In srawls' code for map, he's asking for it to return the keys to the anonymous hash at $hash{$_}. Since he's evaluating it in scalar context, it returns the total number of elements, instead of the keys. This code is equivalent to:
my $numSubKeys = 0;
foreach ( keys %hash ) {
$numSubKeys += scalar keys %{$hash{$_}} };
}
Of course, as srawls mentioned, it loops. There's really no way around this (that I can see).
Cheers,
Ovid
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats. | [reply] [d/l] |
I concur with Ovid on srawls' solution: very slick indeed.
The reason I'm trying to get at a scalar value for the subkeys
in a %HashOfHashes without looping is because I'm already
iterating through the keys/subkeys.
What I'm really trying to do: given a %HoH, iterate through
the subkeys and display each $interval group of subkeys
(where $interval is a positive integer). Of course, when
I get to the end, I'll need to kick out the last group even
though the counter never gets to $interval.
Example and pseudocode: my %HoH contains 97 subkey-value pairs
(but I don't it's 97).
$interval = 10;
foreach $key (keys %HoH) {
if ($interval % $counter == 0) {
display(\%tmp);
$counter = 0; # reset the counter
}
foreach $subkey (keys %{$HoH{$key}}) {
$tmp{++$counter} = "$key -- $subkey";
}
}
The problem I run into is when $counter is a remainderless
divisor of $interval (ie, $counter = 1). I can kludge around
this obstacle by doing a sort of --$secondary_counter decrement
if I knew the total number of subkeys with which I could compare
$secondary_counter. This is where srawls' golfing looks great
but then I'd be iterating over the hash twice.
Muchas gracias,
"dogs luv me cuz i'm crazy sniffable / i bet you never knew i got the ill peripherals" | [reply] [d/l] |
I'd replace %tmp with @tmp, replace $counter with scalar(@tmp), replace $counter=0 with @tmp=(), and replace your last line with
push @tmp, "$key -- $subkey";
I don't think your sample code works very well, but I'll assume that this is just a problem with the sample more so than the code you are really working with. But you shouldn't need the total number of subkeys in order to be able to handle those boundary cases. If you post some more accurate sample code that shows how you are trying to deal with the boundary case, we can probably help you figure that out.
-
tye
(but my friends call me "Tye")
| [reply] [d/l] |
Argh!(tm) I just love when I wrack for a few hours then
turn around and just see the solution like a big flashing
neon sign in the middle of the night!
Instead of:
if ($interval % $counter == 0)
I should've used:
if ($counter % $interval == 0)
No need to worry about "remainderlessness" that way.
Thanks all for input.
"dogs luv me cuz i'm crazy sniffable / i bet you never knew i got the ill peripherals" | [reply] [d/l] [select] |
$numSubKeys = map keys %$_, values %hash;
MeowChow
s aamecha.s a..a\u$&owag.print | [reply] [d/l] |
$n=map keys%$_,each%h
Update:Whoops, as MeowChow pointed out, this doesn't work for hashes with more than one key.
The 15 year old, freshman programmer,
Stephen Rawls | [reply] [d/l] [select] |