Am Dienstag, 3. Mai 2005 03.30 schrieb [EMAIL PROTECTED]: > > * If the format of all your data lines is "consistent", you could use > > split > > > on \s+ to get the data fields instead of a tr/m cascade. > > > > * Then, if I understand you correctly, you wantto build a hash with % > > keys > > > and F... values. This could be done with code like > > > > push @{$lookup_hash{$pct_value}}, $F_value; > > > > eventually, you even want a 2nd level hash with the F field number as > > key, > > > if the F values are unique over the whole file and the last field alway > > begins with an F. > > === test5.pl === > #!/usr/bin/perl > > use warnings; use strict; > > my @lines=split "\n", <<EOF; > 1 2005/01/20 15:39 17 2% -il-o-b----- sg F01000 > 2 2005/01/20 15:53 14 1% -il-o-b----- sg F01001 > 3 2005/01/18 09:53 2 0% -il-o-b----- sg F01002 > 4 2005/02/04 16:41 196 100% -il-o-b----f sg F01003 > 5 2005/02/05 21:13 305 100% -il-o-b----f sg F01004 > EOF > > my %lookup; > foreach (@lines) { > my @fields=split /\s+/; > push @{$lookup{$fields[4]}}, $fields[7]; > } > > print join "\n", map {$_.": ".(join ", ", @{$lookup{$_}})} sort {$a <=> $b} > > keys %lookup; > print "\n"; > === end test5 pl === > > This prints: > > 0%: F01002 > 1%: F01001 > 2%: F01000 > 100%: F01003, F01004 > > ++++++++++++++++++++++++++++++++ > > ok thank you, but a few questions: > > 1) In programming Perl, it states one cannot push or pop a hash on page 10 > paragraph 2. "You cannot push or pop a has b/c it does not make sense; a > hash has no beginning nor end."
True :-) > Why does Oreilly's PP 3rd edition say this? Hm... because its true :-)) > It looks like you are pushing data elements from @lines into > %lookup, correct? (Please bear with my english while I try to explain...) The data structure built in the foreach loop looks like my %lookup=( key1 => ['val1a', 'val1b'] # etc. - note A key2 => ['val2a', 'val2b'] # etc. - note B ) This means that key1 and key2 are (ordinary) hash keys, and the lines commented with "note A/B" are (nearly ordinary) scalar values: The scalars are not "123" or "string", but arrayrefs (which are, like all refs, scalar values). The push is done at the end of these _dereferenced_ arrayrefs (read: the arrays). These arrays are initialized automagically at the time of the first push to them. The dereferencing is done by the '@{}' in push @{ $lookup{$fields[4]} }, $fields[7]; while $lookup{$fields[4]} itself is the reference to the array (read: an arrayref). > 2) Is this : print join "\n", map {$_.": ".(join ", ", @{$lookup{$_}})} > sort {$a <=> $b} > > stating > > for every $_ construct or default variable, No, you did not cite the part "keys %lookup;" > join newline to a > map of : any character with a comma then space then the data elements > from $lookup > sorted. I add some formatting to explain. It's best understood if read backwards, from "keys %lookup" to "print"; imagine the execution flow in this direction: print join "\n", map { $_ . ": " . ( join ", ", @{$lookup{$_}} ) } sort {$a <=> $b} keys %lookup; "Take the keys from %lookup into $_, then sort $_ numerically, then use a map{} to format a string of every single hash key (in $_) and the corresponding array elements accessed via the 'scalar arrayref hash value' (again, @{} dereferences the arrayref). The map results in a string for every $_. These are concatenated by a newline and printed. This could be written the long way (but now to be read topdown): my @keys=keys %lookup; my @sorted_keys=sort {$a <=> $b} @keys; my @per_key_strings; foreach my $k (@sorted_keys) { push @per_key_strings, $k . ": " . ( join ", ", @{$lookup{$_}} ); } print join "\n", @per_key_strings; > 3) I know I can populate an array like so: > my (@array, $i ) = (); my (@array, $i); or, for clarity: my @array; # no need to initialize with () my $i=0; # explicitly state start value > foreach > (<FH>) { $array[$i++] } What's the sense of it since you don't assign any array element? > As an example, is it incorrect to do likewise to a hash as so: > my %HoA = (); > for (<FH> ) { > $HoA{$i++} = (split)[-1] > } Looks correct to me. If I wanted to be shure, I would run the code and then inspect the resulting data structure :-) But, as somebody else already mentioned, it makes not much sense to use a hash with keys from 0..n, this could be done with an array containing elements 0..n. > 4) for my $d (keys %HoA) { > print "$d: @{$HoA{$d} }\n"; Maybe the @{} here confuses in combination with above @{} that was used to "intentionally" dereference a scalar arrayref. Here, @{} is a common way to interpolate one or more data elements into a string - also by dereferencing an arrayref which is formed by the value(s) - in most cases just one - within the @{}. > } > > This was from copied from programming perl and strict did not complain > and prints out the hash values. Is there a better way? I don't think so. But there are other ways to do it, for instance, avoiding @{}, print "$d: ", $HoA{$d}, "\n"; I must admit that I had big problems with the english, maybe I missed the overview of your question(s), but hope it was understandable. joe. -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>