2

動作しているコードがいくつかありますが、多くの警告を吐き出しています。

    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 に到達することはありませんが、コードをより堅牢にしたいと考えています。

ありがとう

4

2 に答える 2

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 を明示的にチェックしてください(ソートのコード ブロックは、負、0、または正の ala " <=>" を返す ANY 式であることに注意してください:

    sort { defined $item_rank{$a}
         ? defined $item_rank{$b}
         ? $item_rank{$a} <=> $item_rank{$b} : 1 : -1 } @items;
    
于 2012-06-06T15:01:56.253 に答える
3

ランク付けされていないレコードの基準が明確に定義されているため、2 つのグループを分離することもできます。

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

次に、通常どおりに並べ替えることができ、2 つの配列を同じ for ループに含めることもできます。

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

これにより、ランク付けされていないすべてのアイテムが自動的に最後に配置されます。

の要素がの引数の一部になるsortのを避けるために、引数を括弧で囲む必要があることに注意してください。演算子を使用して、print ステートメントで未定義の値をチェックしました。@unrankedsortdefined-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) { 
...
于 2012-06-06T16:37:39.423 に答える