710661809 发表于 2015-12-28 09:35:22

Perl小知识点之排序sort

  脚本这种东西,就是要常用,否则一段时间不用就生疏了,因此决定时时记一些小知识点,一来回顾一下,二来需要的时候可以迅速获得提示。
  Sort by number
  You could now write a numeric sort subroutine like this:



1 sub by_number {
2   # a sort subroutine, expect $a and $b
3   if ($a < $b) { –1 } elsif ($a > $b) { 1 } else { 0 }
4 }
  To use the sort subroutine, just put its name (without an ampersand) between the keyword sort and the list you’re sorting. This example puts a numerically sorted list of numbers into @result:



my @result = sort by_number @some_numbers;
  Notice that you don’t have to do anything in the sort subroutine to declare $a and $b and set their values—and if you did, the subroutine wouldn’t work right. We just let Perl set up $a and $b for us, so all you need to write is the comparison.
  In fact, you can make it even simpler (and more efficient).Perl has a convenient shortcut to use to write it. In this case, you use the spaceship operator (<=>). This operator compares two numbers and returns –1, 0, or 1 as needed to sort them numerically.



sub by_number { $a <=> $b }
  Sort by strings
  three-way string-comparison operator: cmp. These two are easy to remember and keep straight.


[*]>=有两种可能的返回值,而<=>有三种可能的返回值,因为>=是两个字符,<=>是三个字符。同样道理,
[*]ge有两种可能的返回值,而cmp有三种可能的返回值,因为ge有两个字符,而cmp有三个字符。



sub by_code_point { $a cmp $b }
my @strings = sort by_code_point @any_strings;
  But you can use cmp to build a more complex sort order, like a case-insensitive sort:



sub case_insensitive { "\L$a" cmp "\L$b" }
  In this case, you’re comparing the string from $a (forced to lowercase) against the string from $b (forced to lowercase), giving a case-insensitive sort order.
  Hash sort: Sorting a Hash by Value



my %score = ("barney" => 195, "fred" => 205, "dino" => 30);
my @winners = sort by_score keys %score;
sub by_score { $score{$b} <=> $score{$a} }
  注意这里$b在$a前面,因为我们希望是按照分数降序排列。
  如果有分数相同的怎么办?按照名字字母排序:



my %score = (
"barney" => 195, "fred" => 205,
"dino" => 30, "bamm-bamm" => 195,
);
my @winners = sort by_score_and_name keys %score;
sub by_score_and_name {
$score{$b} <=> $score{$a} # by descending numeric score
    or
$a cmp $b               # code point order by name
}
  当分数相同是,$score{$b} <=> $score{$a}返回0,因此执行短路操作符or之后的语句:$a cmp $b,按照名字字母排序。
  <over>
  以上摘自:《Learning Perl 6th Edition》
  
页: [1]
查看完整版本: Perl小知识点之排序sort