in reply to Re^3: Counting Problem
in thread Counting Problem

Robticus,

The data structure that I want is in fact the one you had mentioned (i.e. A Hash of Hashes). My code has been generating this kind of structure.

#Foreach that loops through @rows which stores data from a CSV file. foreach my $rec (@rows) { foreach my $dept (@Divisions) { if ($rec->[5] =~ /^$dept/ && $rec->[8] =~ /^P\W[1-5]|D\W[1 +-2]|AD\w|DD\w|DG/) { my $Rec = { GRADE=>strip_hyphen($rec->[0]), POSITION=>$rec->[1], NAME=>invert_name($rec->[2]) + }; #The Divison is then added here push @{$AG{$rec->[4]}},$Rec; } } } <code> Dump of the %AG structure generated by logic above: VAR1 = 'ESRD - Office of Director'; $VAR2 = [ { 'NAME' => 'A. Smith', 'POSITION' => 'DIRECTOR', 'GRADE' => 'D1' }, { 'NAME' => 'P. Green', 'POSITION' => 'SENIOR DIRECTOR', 'GRADE' => 'D2' } ]; $VAR3 = 'BERF - Office of Technology'; $VAR4 = [ { 'NAME' => 'G. Tekola', 'POSITION' => 'JUNIOR OFFICER', 'GRADE' => 'P1' }, { 'NAME' => 'P. Brown', 'POSITION' => 'JUNIOR OFFICER', 'GRADE' => 'P1' }, { 'NAME' => 'T. Green', 'POSITION' => 'Technology Officer', 'GRADE' => 'P2' }, { 'NAME' => 'T. Green', 'POSITION' => 'Technology Officer', 'GRADE' => 'P2' }, { 'NAME' => 'T. Green', 'POSITION' => 'Technology Chief', 'GRADE' => 'P3' }, ];
I then can access the data using the following logic:
foreach my $A (sort keys %AG) { foreach my $p ( sort { substr($$a{GRADE},0,1) cmp substr($$b{GR +ADE},0,1) || substr($$b{GRADE},0,2) cmp substr($$a{GRADE},0,2)} @{$AA +{$A}}) { my( $grade_nums,$grade, $name,$position ) = ($p->{GRADE_NUMS},$p->{'G +RADE'}, $p->{'NAME'},$p->{'POSITION'} ); print $grade_nums,$grade, $name,$position,"\n"; } }
How do I then implement you counter logic in this type of structure? A small pointer would be appreciated. I did read Perldesc which helped me to develop my data structure. Maybe I need to change it? And yes, I will try to invest in a good editor. Maybe Komodo.

Replies are listed 'Best First'.
Re^5: Counting Problem
by roboticus (Chancellor) on Sep 11, 2014 at 15:36 UTC

    You could use slot 0 of your array to hold the count, and let the names occupy slots 1..n. That would give you a structure like:

    my %AG = ( 'OfficeOfDir' => [ 5, # slot 0 holds count { GRADE=>'A', POSITION=>'Quarterback', NAME=>'Unitas, J.' }, { GRADE=>'B', POSITION=>'Nickleback', NAME=>'Elephino' }, ], 'OfficeOfTech' => [ 2, { GRADE=>'B2', POSITION=>'Secretary', NAME=>'BillTheGalacticHe +ro' }, { GRADE=>'C5', POSITION=>'Diplomat', NAME=>'StainlessSteelRat +' }, ], );

    There are many alternatives, though. You need to come up with something that feels natural to you, and you find easy to work with in your code.

    Also, I wasn't kidding when I mentioned:

    • Indentation will help you gain speed and accuracy, and
    • Use a reference with Dumper so you can get a simpler view of your data.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      Robitcus,

      Many thanks for all your guidance.

      One last question. When you are composing your data structure, I noticed that you are pushing 3 values (i.e.push @{ $grades{$_->{GRADE}}{$_->{POSITION}} }, $_->{NAME} for @$RECORD).

      How would I go about adding additional values into the @$grades hash such as $_{SECTION},$_{AGE} etc so that they are outputted as follows: GRADE, POSITION, NAME, SECTION, AGE etc.?

      I can't figure out how to add additional hash keys.

      Thanks.

        GuiPerl:

        If you use Dumper to print out the data structure, you can look at the structure to see what to do. For example:

        $VAR1 = ( # top level look at next item to see if array + or hash FOO=>{ # Key: top level is hash. { means next is ha +sh too BAR=>{ # another hash BAZ=>[ # square bracket starts an array { BIM=>1 }, # slot 0 contains a hash { BIM=>5 }, # slot 1 also contains a hash 'GEORGE', # slot 2 holds a string [3,6,9] # slot 3 holds an array }, }, }, FOE=>[ # FOE is key for an array ['a','b','c'], # slot 0 holds another array {FUM=>'FIE'}, # slot 1 holds a hash ], ); say $H{FOO}{BAR}{BAZ}[0]{BIM}; # should show 1 say $H{FOO}{BAR}{BAZ}[2]; # should show GEORGE say $H{FOO}{BAR}{BAZ}[3][1]; # should show 6 say $H{FOE}[0][2]; # should show c say $H{FOE}[1]{FUM}; # should show FIE

        So look at your Dumper output, and look at the characters used to separate the levels. You'll want to use the same characters to get to the data you want. Does that help clear things up?

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.