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


In reply to Re: Brain muchly befuddled by nested hashes by johngg
in thread Brain muchly befuddled by nested hashes by WartHog369

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.