Stuart White wrote:
> --- Rob Dixon <[EMAIL PROTECTED]> wrote:
> > Stuart White wrote:
> > > I have a hash called fouls.  Within that hash, there
> > > are other hashes called offensive, personal, and
> > > shooting.  The keys to those hashes are names, like
> > > Smith, Rodriguez, and Chan.  and the values to those
> > > names are numbers.
> > > I think if I wanted to access the number of offensive
> > > fouls Chan committed, the syntax would be this:
> > >
> > > $fouls{$offensive}{$Chan};
> > >
> > > Is that right?
> >
> > Yes, as long as you have a named hash %fouls. If it
> > is an anonymous hash referenced by scalar $fouls,
> > then
> > you want
> >
> >   $fouls->{$offensive}{$Chan};
> >
>
> Whew, good thing for my ego that I got that one right.
> I do have a hash named %fouls.  No references yet,
> that's next.
>
> > > Assuming it is, and I have a file that is collecting
> > > the lines that indicate fouls, then of those,
> > > separating the ones that indicate offensive, personal
> > > and shooting, and then of those the ones that indicate
> > > Smith, Chan and Rodriguez and then increment each
> > > instance.  If my backreference variable $3 was storing
> > > on each pass in the while loop the type of foul
> > > (offensive, personal or shooting) and $1 was storing
> > > the name (Chan, Rodrigues or Smith)
> >
> > OK lets stop there. I don't think you want to do it
> > like
> > that. If, as you say, you have foul type in $3 and
> > player name in $1 then you want to accumulate them
> > like
> > this
> >
> >   $fouls{$3}{$1}++;
> >
>
> Yes, I'd want to use the backreferenced variables
> within the loop, the name of the foul and the name of
> the player was just for illustration.  I guess I
> didn't clear that up.  My mistake.
>
> Strangely enough, I still don't quite understand
> completely what that's doing, but what I'm hoping that
> syntax does is distinguish each player name and each
> type of foul and group the kinds of fouls with each
> player that committed them, and the count.

Conceptually, what you have is a tree. There are three
branches from the root, one for each foul type, and
each of these is split into a further three branches,
one for each player.

Internally what you have is a hash, %fouls, which relates
foul types (as the hash keys) to hash references (as the
values). Each of these references refer to a hash which
relates player names (as the keys) to foul count (as
the values).

It may be helpful to do this

  use Data::Dumper;
  print Dumper \%fouls;

which will output Perl code to reconstruct the hash
contents. It provides a useful visual representation
of the hash you've built.

> I took a bit of a leap from this earlier example:
> $fouls{$1}++;
> Which kept track of the number of fouls for each
> player, but grouped all fouls together.
>
> > which, if $1 eq 'Chan' and $3 eq 'offensive' would
> > increment the element
> >
> >   $fouls{offensive}{Chan}
> >
> > Which is a lot nicer as you don't then have to
> > declare
> > a scalar variable for every possible player. Be
> > careful about upper and lower case characters
> > though:
> > as far as Perl's concerned 'Chan' and 'chan' are two
> > different players!
> >
>
> Yup, the nomenclature for the names, fouls and
> everything with the log is standardized, so I won't
> run into 'chan' and 'Chan.'  thanks for the heads up
> though.
>
> > > How would I print the %fouls hash out so that the
> > > output would be grouped by type of foul?  Here is
> > > an example of the output I'd like to see.
> > >
> > > Offensive fouls:
> > > Chan: 3
> > > Rodriguez: 1
> > > Smith: 1
> > >
> > > Personal fouls:
> > > Chan: 1
> > > Rodriguez: 4
> > > Smith: 1
> > >
> > > Shooting fouls:
> > > Chan: 1
> > > Rodriguez: 1
> > > Smith: 2
> > >
> > > would I nest foreach loops?  If so, I'm still not
> > > sure how I'd do that.
> >
> > You'd have to look at the three subhashes
> > separately. Try this
> >
> >   foreach $type ( qw/Offensive Personal Shooting/ )
> > {
> >     printf "%s fouls\n", $type;
> >     my $rank = $fouls{lc $type};
> >     foreach my $player (keys %$rank) {
> >       printf "%s: %d\n", $player, $rank->{$player};
> >     }
> >   }
> >
>
> Hmm, it's not.

Not what? :)

> I'm getting confused by the variable
> names and what each represent since the $1 or the $3
> isn't in there.

Scalar $type holds the foul type. The same as $3 on input.
Scalar $player holds the player name. The same as $1 on input.

> Also, can I do it without the reference?

You can do it without the hash reference but it looks more
confusing that way. You can't get around the fact that the
level 2 hashes are anonymous ones so you need to understand
references.

  foreach my $type ( qw/Offensive Personal Shooting/ ) {
    printf "%s fouls\n", $type;
    foreach my $player ( keys %{$fouls{$type}} ) {
      printf "%s: %d\n", $player, $fouls{$type}{$player};
    }
  }

Cheers,

Rob




-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to