Perl小知識點之排序sort

腳本這種東西,就是要經常使用,不然一段時間不用就生疏了,所以決定時時記一些小知識點,一來回顧一下,二來須要的時候能夠迅速得到提示。ui

Sort by numberthis

You could now write a numeric sort subroutine like this:spa

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:code

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.blog

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 stringsthree

three-way string-comparison operator: cmp. These two are easy to remember and keep straight.ip

  • >=有兩種可能的返回值,而<=>有三種可能的返回值,由於>=是兩個字符,<=>是三個字符。一樣道理,
  • 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: ci

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. rem

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》

相關文章
相關標籤/搜索