2012-06-06 61 views
2

我有一些代碼正在工作,但吐出了很多警告。perl最大標量值

foreach my $item (sort {$item_rank{$a} <=> $item_rank{$b}} @items{ 
     ... 
    } 

我的問題是,不是每個項目都有排名,所以我的輸出是亂七八糟的警告。我想讓最後沒有等級的物品。 我想到的代碼更改爲如下:

foreach my $item (sort { 
           $item_rank{$a} = 99999 if(!exist $item_rank{$a}); 
           $item_rank{$b} = 99999 if(!exist $item_rank{$b}); 
           $item_rank{$a} <=> $item_rank{$b}} @items{ 
     ... 
    } 

我的問題是,有沒有我可以設置它,而不是99999特定值,但我永遠不會在我的當前設置達到99999,我希望我的代碼更健壯。

感謝

+0

不要只是說'「警告」'警告,說什麼樣。 – TLP

回答

4

你可以做的2種方式是一個:

  • 如果您已經定義了最大上限,默認爲它(爲了簡化代碼,我假設0不是有效的秩)

    $max_ceiling = 99999; 
    sort { ($item_rank{$a} || $max_ceiling) 
        <=> ($item_rank{$b} || $max_ceiling) } @items 
    

    或者,要避免分配到哈希:

    # Ideally, %item_rank should be passed as a parameter but meh. 
    sub rank4comp { exist $item_rank{$_[0]} ? $item_rank{$_[0]} : 999999; } 
    sort { rank4comp($a) <=> rank4comp($b) } @items; 
    
  • 更重要的是,在你的表達檢查undefs明確(記住sort's code block可以是任意表達式,它返回負數,0或正ALA 「<=>」:

    sort { defined $item_rank{$a} 
        ? defined $item_rank{$b} 
        ? $item_rank{$a} <=> $item_rank{$b} : 1 : -1 } @items; 
    
+2

海事組織的最後一個是完美的,前兩個甚至不應該考慮。 –

3

既然你有對於未排序記錄的標準明確的定義,你可能也只是分開兩組:

my @unranked = grep ! defined($item_rank{$_}), keys %item_rank; 
my @ranked = grep defined($item_rank{$_}), keys %item_rank; 

然後你就可以進行排序按通常,你甚至可以包括在相同的兩個數組for循環:

for my $item (sort ({ $item_rank{$a} <=> $item_rank{$b} } @ranked), @unranked) { 
    print "$item => ", $item_rank{$item} // "N/A", "\n"; 
} 

這將自動把所有未排序項最後。

請注意,您需要圍繞參數sort的參數,以避免@unranked的元素成爲參數sort的一部分。我使用defined-or運算符//檢查打印語句中的未定義值。

,你甚至可以拉昇的排序爲grep聲明:

my @unranked = grep ! defined($item_rank{$_}), keys %item_rank; 
my @ranked = sort { $item_rank{$a} <=> $item_rank{$b} } 
        grep defined($item_rank{$_}), keys %item_rank; 

for my $item (@ranked, @unranked) { 
... 
+0

+1 - 不錯的做法 – DVK

+0

@DVK謝謝。 – TLP