cvs commit: perlfaq perlfaq4.pod perlfaq5.pod

[email protected] (brian d foy) 27 Oct 2005 20:27:31 -0000
Newsgroups perl.cvs.perlfaq
Message-ID <[email protected]>
cvsuser     05/10/27 13:27:30

  Modified:    .        perlfaq4.pod perlfaq5.pod
  Log:
  * perlfaq4: How do I sort a hash (optionally by value instead of key)?
  	+ I completely replaced the answer to disambiguate the "sort key"
  	and "hash key"
  
  * perlfaq5: How do I get a file's timestamp in perl?
  	+ re-ordered the file test operators to parallel their mentions
  	in the prose
  
  Revision  Changes    Path
  1.70      +45 -22    perlfaq/perlfaq4.pod
  
  Index: perlfaq4.pod
  ===================================================================
  RCS file: /cvs/public/perlfaq/perlfaq4.pod,v
  retrieving revision 1.69
  retrieving revision 1.70
  diff -u -r1.69 -r1.70
  --- perlfaq4.pod	14 Oct 2005 15:34:06 -0000	1.69
  +++ perlfaq4.pod	27 Oct 2005 20:27:30 -0000	1.70
  @@ -1786,27 +1786,50 @@
   
   =head2 How do I sort a hash (optionally by value instead of key)?
   
  -Internally, hashes are stored in a way that prevents you from imposing
  -an order on key-value pairs.  Instead, you have to sort a list of the
  -keys or values:
  -
  -    @keys = sort keys %hash;	# sorted by key
  -    @keys = sort {
  -		    $hash{$a} cmp $hash{$b}
  -	    } keys %hash; 	# and by value
  -
  -Here we'll do a reverse numeric sort by value, and if two keys are
  -identical, sort by length of key, or if that fails, by straight ASCII
  -comparison of the keys (well, possibly modified by your locale--see
  -L<perllocale>).
  -
  -    @keys = sort {
  -		$hash{$b} <=> $hash{$a}
  -			  ||
  -		length($b) <=> length($a)
  -			  ||
  -		      $a cmp $b
  -    } keys %hash;
  +(contributed by brian d foy)
  +
  +To sort a hash, start with the keys. In this example, we give the list of
  +keys to the sort function which then compares them ASCIIbetically (which
  +might be affected by your locale settings). The output list has the keys
  +in ASCIIbetical order. Once we have the keys, we can go through them to
  +create a report which lists the keys in ASCIIbetical order.
  +
  +	my @keys = sort { $a cmp $b } keys %hash;
  +	
  +	foreach my $key ( @keys )
  +		{
  +		printf "%-20s %6d\n", $key, $hash{$value};
  +		}
  +
  +We could get more fancy in the C<sort()> block though. Instead of 
  +comparing the keys, we can compute a value with them and use that
  +value as the comparison.  
  +
  +For instance, to make our report order case-insensitive, we use
  +the C<\L> sequence in a double-quoted string to make everything 
  +lowercase. The C<sort()> block then compares the lowercased
  +values to determine in which order to put the keys.
  +
  +	my @keys = sort { "\L$a" cmp "\L$b" } keys %hash;
  +	
  +Note: if the computation is expensive or the hash has many elements,
  +you may want to look at the Schwartzian Transform to cache the 
  +computation results.
  +
  +If we want to sort by the hash value instead, we use the hash key
  +to look it up. We still get out a list of keys, but this time they
  +are ordered by their value.
  +
  +	my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash;
  +
  +From there we can get more complex. If the hash values are the same,
  +we can provide a secondary sort on the hash key.
  +
  +	my @keys = sort { 
  +		$hash{$a} <=> $hash{$b} 
  +			or
  +		"\L$a" cmp "\L$b"
  +		} keys %hash;
   
   =head2 How can I always keep my hash sorted?
   
  
  
  
  1.39      +2 -2      perlfaq/perlfaq5.pod
  
  Index: perlfaq5.pod
  ===================================================================
  RCS file: /cvs/public/perlfaq/perlfaq5.pod,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- perlfaq5.pod	13 Oct 2005 19:49:13 -0000	1.38
  +++ perlfaq5.pod	27 Oct 2005 20:27:30 -0000	1.39
  @@ -687,7 +687,7 @@
   
   If you want to retrieve the time at which the file was last
   read, written, or had its meta-data (owner, etc) changed,
  -you use the B<-M>, B<-A>, or B<-C> file test operations as
  +you use the B<-A>, B<-M>, or B<-C> file test operations as
   documented in L<perlfunc>.  These retrieve the age of the
   file (measured against the start-time of your program) in
   days as a floating point number. Some platforms may not have