Stuart White wrote: > > > 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. > > > > Like this: > > -->Rodriguez{numFouls} > -->offensive-->Chan{numFouls} > -->Smith{numFouls} > > -->Rodriguez{numFouls} > fouls-->personal-->Chan{numFouls} > -->Smith{numFouls} > > -->Rodriguez{numFouls} > -->shooting-->Chan{numFouls} > -->Smith{numFouls} > > That's what I conceptually see, and what I think it > should be.
That's about it. Your notation isn't consistent but I shouldn't worry about that. > > 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). > > > > internally, that looks like this, right? > $fouls{offensive}{Chan} > > then substitute the foultype and the player name for > the 8 other options. Well, that's just the syntax for extracting a single count from the structure. You need to understand that $fouls{offensive} is a hash reference. That's why I suggested Dumper. > > > It may be helpful to do this > > > > use Data::Dumper; > > print Dumper \%fouls; > > > > the call to print is after I've written the hash, > right? and the use Data::Dumper; is just like typing > use strict; right? I don't have to do anything else > with that I suppose? Yes. Put 'use Data::Dumper' anywhere before you first use it, and 'print Dumper \%fouls' after you've populated the hash. > > I actually did something like this when I had 1-d > hashes, but six of them, one for every different > foul(for simplicity's sake, I've just written names of > 3 diff kinds of fouls), but then I thought I'd have to > write a bunch of lines like you wrote for the 2-d > hash, which I thought would be cumbersome, since there > are plenty of different names. I wrote it that way so that it produced exactly the output that you proposed. The list of foul types is just the list of keys for the %fouls hash,so you could write foreach (keys %fouls) { : } > I had something like: > if ($3 eq 'Offensive') > { > $offensive{$1}++; > } > > That's when he suggested that I didn't have to match > $3 or $1 to anything, and so sent me on a chase to > figure out how. That's how I came up with the thought > that I'm not matching the name in the example above > ($1) so perhaps I could write a line like so: > $fouls{$3}{$1}++; > and that would do the same thing if wrote: > > if ($1 eq 'Chan' and $3 eq 'offensive') > { > $fouls{$3}{$1}++; > } > or something like that. > So this is what I'd like to do, count fouls without > using string comparison operators. You're getting confused between variables and data here. $1, $3, $player, $type etc are all just scalar variables (except that you can't set $1 .. $9 yourself. Perl hash to set them from a regex.) What you're trying to write above is if ($1 eq 'Chan' and $3 eq 'offensive') { $fouls{offensive}{Chan}++; } but then you have to replicate this for every combination of player and foul type, which also means that you have to know what valid values to expect. This may be the case here, when you know what foul types are possible, but you don't want to have to change the program when the team members change. I hope you can see that this is the same as $fouls{$3}{$1}++; or $fouls{$player}{$type}++; without having to test the contents of the variables at all. > > > 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. > > > > Yes, but was supposed to assume that further up in the > code I would have assigned $1 to $player, and $3 to > $type? That's where a lot of my confusion came from. No. Forget about $1 and $3 once you've read your data into the hash. If you want particular values out of the data you can hard-code them like this: foreach my $type ( qw/Offensive Personal Shooting/ ) { my $rank = $fouls{lc $type}; : } or, if you just want all the data in the hash, in no particular order foreach my $type ( keys %fouls ) { my $rank = $fouls{lc $type}; : } > Then, what does $rank refer to? Wait, it looks like > it is assigned to $fouls{$type} Yes. > so then $rank would have a key of foultype, and a > value of player name which is also a key and would > have a value of the number of fouls? Is that it? Careful now! $rank is a scalar variable,and happens to be a hash reference. Going back to the diagram, you've plucked one of the three first level branches off the tree and put it into $rank. The hash it references has the three player names as keys and their foul counts as values. > and I'm not familiar with this syntax: > %$rank If $rank is a hash reference, then %$rank is the hash it refers to. > > > 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. > > > > I asked because I'm still moving in baby steps here. > :) References are next. You can't have multi-dimensional hashes without using references. You can hide the fact that they're references to some extent, but to do anything useful you have to know how to handle references to manipulate the second level and below. > Before this would work, I'd have to assign $3 to > $type and $1 to $player, right? No. This is back to the distinction between data and variables, and between building and using the hash. The regex puts the player name into scalar $1 when you're populating the hash. The 'foreach' loop puts sets $player to the keys (player names) that are in the hash for which you want to access the values. > > 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}; > > } > > } > > Time to go and play with hashes for a while! Start with the simplest imaginable hash my %hash; $hash{A} = 1; and dump it. Then add additional data, then additional levels, and get a feel for what the operations are doing. Cheers, Rob -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]