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

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.

Replies are listed 'Best First'.
Re^4: Counting Problem
by Anonymous Monk on Sep 11, 2014 at 12:16 UTC
    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.

      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.