in reply to Brain muchly befuddled by nested hashes
I think there has been some confusion caused by one of the variable names you have chosen. You use substr to pull a date and time string from your data line. You then use substr again to isolate parts of that string. One of these you call $date but it is, in fact, only the day of the month; perhaps something like $mday would have been a more descriptive choice.
Others have addressed the issue of the fat comma (=>) in your hash key and the resultant odd characters in your keys. I concatenate the text you use with the day or hour value to form the keys by using interpolation in a double-quoted string. Cristoforo thought at a regular expression would be a good choice for extracting the date and time information you require. I would agree but, without seeing your data, I do not know whether there is similarly formatted date & time information earlier in each line. Therefore, I use a combination of substr and a regular expression, using captures in the match to pull out fields of interest (see Extracting matches, perlretut and perlre). Cristoforo also advocated the use of sprintf to format your hours along with a solution using two hashes rather than your one. My code below uses just the one hash and, as ptoulis recommends, avoids some of the redundancy in your data structure. I also avoid some typing in each nested foreach by assigning the hash reference I'm interested in within the structure to a lexical scalar scoped to the loop, see perlreftut and perlref. When incrementing the hourly count for the bottom or top of the hour I use a ternary to decide which hash element to address, see Conditional Operator in perlop.
use strict; use warnings; my %signIn = (); while( <DATA> ) { my $dateStr = substr $_, 42, 17; next unless my( $mday, $hr, $min, $ampm ) = $dateStr =~ m{\d\d/(\d\d)/\d{4}\s+(\d{1,2}):(\d\d)(a|p)}; $hr = 0 if $hr == 12; $hr += 12 if $ampm eq q{p}; $hr = sprintf q{%02d}, $hr; my $mdayKey = qq{DayOfMonth$mday}; my $hrKey = qq{HourSignIn$hr}; $signIn{ $mdayKey }->{ TotalPerDay } ++; $signIn{ $mdayKey }->{ $hrKey }->{ TotalPerHour } ++; $signIn{ $mdayKey }->{ $hrKey }-> { $min < 30 ? q{HalfHour00} : q{HalfHour30} } ++; } foreach my $mdayKey ( sort keys %signIn ) { my $rhDaily = $signIn{ $mdayKey }; print qq{$mdayKey\n}, qq{ TotalPerDay - $rhDaily->{ TotalPerDay }\n}; foreach my $hrKey ( sort grep m{^Hour}, keys %{ $rhDaily } ) { my $rhHrly = $rhDaily->{ $hrKey }; print qq{ $hrKey\n}, qq{ TotalPerHour - $rhHrly->{ TotalPerHour }\n}, qq{ HalfHour00 - }, exists $rhHrly->{ HalfHour00 } ? qq{$rhHrly->{ HalfHour00 }\n} : qq{0\n}, qq{ HalfHour30 - }, exists $rhHrly->{ HalfHour30 } ? qq{$rhHrly->{ HalfHour30 }\n} : qq{0\n}; } } __END__ 0123456789012345678901234567890123456789 06/05/2008 8:31a&&&&&&& abcdefghijabcdefghijabcdefghijabcdefghij 06/07/2008 12:15p&&&&&&& 0123456789012345678901234567890123456789 06/05/2007 1:46p&&&&&&& abcdefghijabcdefghijabcdefghijabcdefghij 06/05/2008 12:49p&&&&&&& This is a line of rubbish that doesn't match the data requirements 0123456789012345678901234567890123456789 06/05/2008 2:24a&&&&&&& abcdefghijabcdefghijabcdefghijabcdefghij 06/05/2007 11:09a&&&&&&& 0123456789012345678901234567890123456789 06/12/2007 12:17a&&&&&&& abcdefghijabcdefghijabcdefghijabcdefghij 06/05/2008 11:09p&&&&&&& 0123456789012345678901234567890123456789 06/05/2008 11:42p&&&&&&&
The output.
DayOfMonth05 TotalPerDay - 7 HourSignIn02 TotalPerHour - 1 HalfHour00 - 1 HalfHour30 - 0 HourSignIn08 TotalPerHour - 1 HalfHour00 - 0 HalfHour30 - 1 HourSignIn11 TotalPerHour - 1 HalfHour00 - 1 HalfHour30 - 0 HourSignIn12 TotalPerHour - 1 HalfHour00 - 0 HalfHour30 - 1 HourSignIn13 TotalPerHour - 1 HalfHour00 - 0 HalfHour30 - 1 HourSignIn23 TotalPerHour - 2 HalfHour00 - 1 HalfHour30 - 1 DayOfMonth07 TotalPerDay - 1 HourSignIn12 TotalPerHour - 1 HalfHour00 - 1 HalfHour30 - 0 DayOfMonth12 TotalPerDay - 1 HourSignIn00 TotalPerHour - 1 HalfHour00 - 1 HalfHour30 - 0
I hope you find these ideas useful.
Cheers,
JohnGG
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Brain muchly befuddled by nested hashes
by WartHog369 (Novice) on Nov 26, 2008 at 06:04 UTC |