2010-06-29 54 views
9

在Perl執行這些行之後:對數組排序參考哈希

my $data = `curl '$url'`; 
my $pets = XMLin($data)->(pets); 

我有一個包含到散列的引用數組引用:

$VAR1 = [ 
     { 
     'title' => 'cat', 
     'count' => '210' 
     }, 
     { 
     'title' => 'dog', 
     'count' => '210' 
     } 
] 

在Perl,如何散列排序首先通過計數,其次通過標題。然後打印到STDOUT計數,然後在每個換行符上標題。

回答

9

假設你想降序計數和職稱升:

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中。 <=>cmphave higher precedence(您可能認爲它們的綁定更緊密),因此它的格式嚴格來說就是||or

要打印數組排序,更熟悉的選擇可能是

foreach my $p (@sorted) { 
    print "$p->{count} $p->{title}\n"; 
} 

Perl使用$_如果不指定獲取每個值的變量,所以下面具有相同的含義:

for (@sorted) { 
    print "$_->{count} $_->{title}\n"; 
} 

forforeach關鍵字是同義詞,但我發現,上面的用途,foreach如果我要去命名VAR否則,for,自然閱讀最自然。

使用mapforeach的近親,反而是沒有太大的不同:

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的應用是你的口味太冗長,然後

​​
+0

什麼是「地圖」的意思/在上面的代碼中做?爲什麼我們不需要在兩個不同的大括號中指定兩個屬性? – syker 2010-06-29 07:05:10

+0

@syker:'map'在你的排序數組中使用每一個散列值,並將它的'count'和'title'值打印在一行,空格分隔。 @gbacon:可能值得解釋一下,在你的排序中使用'||'和'or'是否有任何區別,因爲我總是在排序的例子中看到'||'。在任何情況下,可讀性更強的'或'行爲是否有所不同? – Zaid 2010-06-29 07:35:33

+0

@syker @Zaid查看更新的答案。 – 2010-06-29 15:28:04