假設你想降序計數和職稱升:
print map join(" ", @$_{qw/ count title /}) . "\n",
sort { $b->{count} <=> $a->{count}
||
$a->{title} cmp $b->{title} }
@$pets;
這緊湊的代碼寫在一個實用的風格。爲了幫助理解它,讓我們以更熟悉,更迫切的風格來看待等效代碼。
Perl的sort
運算符接受一個可選的SUBNAME參數,該參數允許您將比較分解出來,並給它起一個描述其作用的名稱。當我這樣做時,我喜歡用by_
開始子名的名稱,以使sort by_...
更加自然。
要開始,你可能已經編寫
sub by_count_then_title {
$b->{count} <=> $a->{count}
||
$a->{title} cmp $b->{title}
}
my @sorted = sort by_count_then_title @$pets;
注意,沒有逗號遵循這種形式的SUBNAME!
要解決其他評論者的問題,如果您發現它更具可讀性,則可以使用or
而不是||
在by_count_then_title
中。 <=>
和cmp
have higher precedence(您可能認爲它們的綁定更緊密),因此它的格式嚴格來說就是||
和or
。
要打印數組排序,更熟悉的選擇可能是
foreach my $p (@sorted) {
print "$p->{count} $p->{title}\n";
}
Perl使用$_
如果不指定獲取每個值的變量,所以下面具有相同的含義:
for (@sorted) {
print "$_->{count} $_->{title}\n";
}
的for
和foreach
關鍵字是同義詞,但我發現,上面的用途,即,foreach
如果我要去命名VAR否則,for
,自然閱讀最自然。
使用map
的foreach
的近親,反而是沒有太大的不同:
map print("$_->{count} $_->{title}\n"), @sorted;
您也可以通過map
促進print
:
print map "$_->{count} $_->{title}\n",
@sorted;
最後,爲了避免重複$_->{...}
,hash slice@$_{"count", "title"}
爲我們提供了與循環當前記錄中的計數和標題相關的值。具有價值,我們需要用一個空格來join他們並追加一個換行符的結果,所以
print map join(" ", @$_{qw/ count title /}) . "\n",
@sorted;
記住qw//
是編寫字符串列表簡寫。正如這個例子所示,讀取一個map
表達式(或者我縮進它的方式):首先對記錄進行排序,然後格式化它們,然後打印它們。
您可以消除暫時@sorted
但撥打指定的比較:
print map join(" ", @$_{qw/ count title /}) . "\n",
sort by_count_then_title
@$pets;
如果join
的應用是你的口味太冗長,然後
什麼是「地圖」的意思/在上面的代碼中做?爲什麼我們不需要在兩個不同的大括號中指定兩個屬性? – syker 2010-06-29 07:05:10
@syker:'map'在你的排序數組中使用每一個散列值,並將它的'count'和'title'值打印在一行,空格分隔。 @gbacon:可能值得解釋一下,在你的排序中使用'||'和'or'是否有任何區別,因爲我總是在排序的例子中看到'||'。在任何情況下,可讀性更強的'或'行爲是否有所不同? – Zaid 2010-06-29 07:35:33
@syker @Zaid查看更新的答案。 – 2010-06-29 15:28:04