3

次のコードの結果が表示されますが、 が次の例 orで何をすべきかを正確に理解していません。sort

use Data::Dumper;

$animals{'man'}{'name'} = 'paul';
$animals{'man'}{'legs'} = 2;
$animals{'cheeta'}{'name'} = 'mike';
$animals{'cheeta'}{'legs'} = 3;
$animals{'zebra'}{'name'} = 'steve';
$animals{'zebra'}{'legs'} = 4;
$animals{'cat'}{'name'} = '';
$animals{'cat'}{'legs'} = 3;
$animals{'dog'}{'name'} = '';
$animals{'dog'}{'legs'} = 4;
$animals{'rat'}{'name'} = '';
$animals{'rat'}{'legs'} = 5;

@animals = sort {
      $animals{$a}{'name'} cmp $animals{$b}{'name'}
   or $animals{$a}{'legs'} <=> $animals{$b}{'legs'}
} keys %animals;

print Dumper(\@animals);
4

3 に答える 3

14

sortsub ( の{}後の部分sort) は、2 層の並べ替えを定義します。最初は名前順、次に脚の数順です。はor、2 つの基準間のクロスオーバーを実装します。コードを別の形式にすると、簡単に確認できます。

@animals = sort {
    $animals{$a}{'name'} cmp $animals{$b}{'name'} or
    $animals{$a}{'legs'} <=> $animals{$b}{'legs'}
} keys %animals;

cmpand演算子は<=>、左の引数が右の引数より小さいか、等しいか、または大きいかに応じて、3 つの値 (-1、0、または 1) のいずれかを返します。(cmp文字列比較を<=>行い、数値比較を行います。) Perl では、0 は false で、-1 と 1 は true です。cmpが真の値を返す場合、はorすぐにその値を返しsort、要素を適切に並べ替えます。cmpが false を返す場合、<=>が評価され、代わりにその結果が返されます。

マルチレイヤーの並べ替えを行う場合、「マップ-並べ替え-マップ」手法 (別名シュワルツ変換) を使用するのが一般的です。

@animals =
  map  { $_->[0] }
  sort {
    $a->[1] cmp $b->[1] ||
    $a->[2] <=> $b->[2]
  }
  map { [$_, $animal{$_}{name}, $animal{$_}{legs}] }
  keys %animal;

明確ではありませんが、通常はパフォーマンスが優れているため、一般的なイディオムです。これは、比較のオペランドが関数である場合に特に重要です。この手法により、比較ごとに不要な (そしてコストがかかる可能性がある) 再計算が回避されます。たとえば、文字列を長さで並べ替える場合、各文字列の長さを 1 回だけ計算する必要があります。

于 2009-06-17T20:41:25.947 に答える
9

orは短絡評価器であるため、真 (0 以外の値) の場合は左側の値を返し、それ以外の場合は右側を評価します。

したがって、この場合、動物の名前が等しい (0 - false) と比較された場合、並べ替えのために足の数がカウントされます。

于 2009-06-17T20:33:55.947 に答える
2

Sort::Key現在のコード全体の代替として提案してもよろしいですか?

use Sort::Key::Multi qw(sikeysort);  # sort keyed on (string, integer)
@animals = sikeysort { $animals{$_}{name}, $animals{$_}{legs} } keys %animals;

# alternately,
use Sort::Key::Maker sort_by_name_then_legs =>
    sub { $animals{$_}{name}, $animals{$_}{legs} }, qw(string integer);
@animals = sort_by_name_then_legs keys %animals;
于 2009-06-17T21:11:07.947 に答える