in reply to Counting Problem

GuiPerl:

You're working too hard generating lines of code, rather than letting perl do the work for you. You should read perldoc perlfaq4, and review the "Data: Hashes (Associative Arrays)" section. It should take you only a few minutes, and it'll show you a simpler way to gather the counts together.

Also, you should keep your code neatly indented so you can see the structure. If everything is haphazardly indented, it's difficult to see the program logic, and that makes the bugs hard to see, too. Either start using an editor that can help you maintain the indentation (vim, Emacs, and a bazillion others), or periodically run your code through perltidy so you can see the code better.

When you write a paper, you'll probably find it easier to write an outline first, so you can plan your work. Proper indentation for coding allows you to see the "outline" of what's going on inside. That'll help you code faster and better.

<end_rant>

...roboticus

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

Replies are listed 'Best First'.
Re^2: Counting Problem
by GuiPerl (Acolyte) on Sep 10, 2014 at 15:01 UTC
    This is wonderful, however, I forgot that my data structure is setup as follows:
    my $Rec = [ {PWD=>posts_outside_pwd($rec->[5])}, {SECTION=>$rec->[14]}, {ORG_LEVEL_DESCRIP=>$rec->[10]}, {GRADE=>strip_hyphen($rec->[15])}, {POSITION=>$rec->[2]}, {NAME=>invert_name($rec->[16])}, {AGE=>convert_date_to_age(trim($rec->[17] +))}, {DATE_OF_BIRTH=>date_of_birth_cleansed($r +ec->[17])}, {COUNTRY=>$rec->[19]}, {FEMALE=>female_staff($rec->[18])}, {VACANT=>vacant_post_yellow_background($r +ec->[16])}, {GRADE_NUMS=>map{++$positions{$_}}$rec->[ +15]." ".$rec->[16]." ".$rec->[2]}, ]; push @{$AG{$rec->[10]}},$Rec; $VAR1 = 'BERF - Office of Director'; $VAR2 = [ [ { 'SECTION' => 'BERF' }, 'GRADE' => 'D1' }, { 'POSITION' => 'DIRECTOR' }, { 'NAME' => 'D. Fool' }, ];
    Each group of staff members is under a group as seen in $VAR1. This line reports an error now:
    push @{ $grades{$_->{GRADE}}{$_->{POSITION}} }, $_->{NAME} for @$AG; #How do I refer @$AG as it is a hash of hashes???
    Thanks again.

      GuiPerl:

      It looks like you munged up the stuff in the code tags, so I'm not sure. However, it looks like you've used Data::Dumper to dump your data. If so, it appears like you might've done something like:

      my %AG = ( 'BERF - Office of Director' => [ [ { SECTION => 'BERF' }, { GRADE => 'D1' }, { POSITION => 'DIRECTOR' }, { NAME => 'D. Fool' }, ] ] ); print Dumper(%AG);

      So to access any element of your data structure, start at the top, and work your way down/in to your data element. So if you want to get the GRADE, you'd need to do something like this:

      my $grade = $AG{'BERF - Office of Director'}[0][0]{GRADE};

      If you look at the data, you can see the nested pair of square brackets: That means that you have an array inside of an array. I suspect that what you *really* wanted is more like this:

      my %AG = ( 'BERF - Office of Director' => { SECTION=>'BERF', GRADE=>'D1', POSITION=>'DIRECTOR', NAME=>'D. +Fool' } );

      This would make %AG a hash of hashes, and you could access GRADE like:

      my $grade = $AG{'BERF - Office of Director'}{GRADE};

      I'd suggest taking a short break from your current project and reading perldoc perldsc, perldoc perlreftut for a little while. Let me know if you need a bit more help.

      Note: Oh, yeah, one other thing: If you're going to use Data::Dumper to print a data structure, be sure to pass a *reference* to the structure into the routine. So you'd use a statement like one of these:

      my %hash = { a=>1, b=>2 }; my $ref = \%hash; # This will give you a nice dump of your hash print Dumper($ref); # This will give you the same kind of dump print Dumper(\%hash); # This will give you a *HORRIBLE* dump: print Dumper(%hash); # It'll give you something like: $VAR1 = 'a'; $VAR2 = 1; $VAR3 = 'b'; $VAR4 = 2;

      ...roboticus

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

        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.