After hours of pondering and sitting in wonder of simple it is, I have come up with something. I do believe that this:
for my $i (0..$#keys) { Quite possibly should be foreach ( @keys ) { Otherwise, why would you have my @keys = (0, 1, 2, 3); Instead of just $keys = 3 and then 0..$keys. If there is any wrong in this thinking, please lemme know. Thank you. -Jess -----Original Message----- Okay, I came up with two solutions. The first is to use eval to build the hash and recursive functions to deal with it. The second takes up more space, but is easier to deal with: cat the keys together. The first is better when you have many things that are going to be the same and the key size is large. <data name="test.data"> this is a test this is a test this is a test that was a test oh my a test oh my a test oh my a test I happen five times I happen five times I happen five times I happen five times I happen five times I happen six times I happen six times I happen six times I happen six times I happen six times I happen six times </data> <example name="t.pl"> #!/usr/bin/perl -w use strict; use Data::Dumper; my %eval_hash; my %cat_hash; my @keys = (0, 1, 2, 3); #eval method, ugly while (<>) { chomp; my @fields = split; #eval method my $eval_str = '$eval_hash'; for my $i (0..$#keys) { $eval_str .= "{$fields[$i]}"; } $eval_str .= "++"; eval $eval_str; #cat method my $key; for my $i (0..$#keys) { $key .= "$fields[$i]-"; } chop $key; #get rid of last '-' $cat_hash{$key}++; } print "%eval_hash:\n", Dumper(\%eval_hash); print_eval_hash("", \%eval_hash); print "\n\n%key_hash:\n", Dumper(\%cat_hash);; print "$_ = $cat_hash{$_}\n" foreach (sort keys %cat_hash); sub print_eval_hash { my ($key, $ref) = @_; if (ref $ref eq 'HASH') { foreach (sort keys %{$ref}) { print_eval_hash("$key-$_", $ref->{$_}); } } else { $key =~ s/-//; #get rid of first - print "$key = $ref\n"; } } </example> <output from="./t.pl test.data"> %eval_hash: $VAR1 = { 'this' => { 'is' => { 'a' => { 'test' => '3' } } }, 'I' => { 'happen' => { 'five' => { 'times' => '5' }, 'six' => { 'times' => '6' } } }, 'that' => { 'was' => { 'a' => { 'test' => '1' } } }, 'oh' => { 'my' => { 'a' => { 'test' => '3' } } } }; I-happen-five-times = 5 I-happen-six-times = 6 oh-my-a-test = 3 that-was-a-test = 1 this-is-a-test = 3 %key_hash: $VAR1 = { 'I-happen-six-times' => '6', 'oh-my-a-test' => '3', 'this-is-a-test' => '3', 'I-happen-five-times' => '5', 'that-was-a-test' => '1' }; I-happen-five-times = 5 I-happen-six-times = 6 oh-my-a-test = 3 that-was-a-test = 1 this-is-a-test = 3 </output> On Fri, 2002-02-01 at 15:58, Balint, Jess wrote: > The way I have the argument parsing set up is for ( 0..$#ARGV ) { . . . > When a -f n is presented on the command line, n will be the field number for > the first hash. > So if I use -f 1 -f 2 -f 3, there will be three levels of hashes. The top > level will contain all unique values in the first field of the file. The > second level will contain all unique values unique to the top level, and the > third level will be unique to the first and second level. The value of the > third level key will be a count of the occurance of all the values together > in the same line. > > -----Original Message----- > > On Fri, 2002-02-01 at 15:23, Balint, Jess wrote: > > A scalar value based on the number of command line arguments put into an > > array. > > > > if( $ARGV[$_] =~ /^-f/ ) { > > # PARSE TABULATION VALUES > > if( $table ) { > > $table = $ARGV[$_]; > > $table =~ s/-f//; > > $table = $ARGV[$_+1] if( length( $table ) == 0 ); > > $tables[$tblcnt] = $table; > > $tblcnt++; > > } else { > > $table = $ARGV[$_]; > > $table =~ s/-f//; > > $table = $ARGV[$_+1] if( length( $table ) == 0 ); > > $tables[0] = $table; > > $tblcnt++; > > } > > > <snip /> > > First off, you don't need $tblcnt. @tables in a scalar context will > return the number of elements and you can simply push the value onto the > array (see perldoc -f push). This also gets rid of the if $table > business. > > Second off, I assume that you are trying to treat -f table and -ftable > the same. In which case shouldn't you increment $_ if you grab the next > arg? > > if ( $ARGV[$_] =~ /^-f(.*)/ ) { > # PARSE TABULATION VALUES > if (defined($1)) { #if there was something after -f > push @tables, $1; > } else { #otherwise use next arg > $_++; > push @tables, $ARGV[$_]; > } > } > > print "There were ", scalar(@tables), "tables on the cmdline.\n"; > > > Thirdly, where are the keys for the hashes going to come from? And how > are you going to know at which level in the hash you want to store the > data? > > To clarify: > In my example I read the keys from the first three words of a line where > the first word was the first key, the second word was the second key, > and the third word was the the third key and then treated the fourth > word as the data. > > -- > Today is Boomtime the 32nd day of Chaos in the YOLD 3168 > Hail Eris! > > Missle Address: 33:48:3.521N 84:23:34.786W -- Today is Pungenday the 33rd day of Chaos in the YOLD 3168 Hail Eris! Missle Address: 33:48:3.521N 84:23:34.786W -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]