Perl 按字典顺序排序

Perl 按字典顺序排序,perl,sorting,cmp,lexicographic,Perl,Sorting,Cmp,Lexicographic,我看到了以下代码的结果,但我不太清楚或如何在下面的排序示例中知道该做什么: 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'

我看到了以下代码的结果,但我不太清楚
如何在下面的
排序
示例中知道该做什么:

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);
使用数据::转储程序;
$动物{'man'}{'name'}='paul';
$animes{'man'}{'legs'}=2;
$animes{'cheeta'}{'name'}='mike';
$animes{'cheeta'}{'legs'}=3;
$animals{'zebra'}{'name'}='steve';
$animals{'zebra'}{'legs'}=4;
$animals{'cat'}{'name'}='';
$animes{'cat'}{'legs'}=3;
$animals{'dog'}{'name'}='';
$animes{'dog'}{'legs'}=4;
$animals{'rat'}{'name'}='';
$animes{'rat'}{'legs'}=5;
@动物=分类{
$animals{$a}{'name'}cmp$animals{$b}{'name'}
或$ANCES{$a}{'legs'}$ANCES{$b}{'legs'}
}关键点是%的动物;
打印转储程序(\@动物);

是一个短路求值器,因此如果为真,它将返回左侧的值(任何非零值),否则将计算右侧的值

因此,在这种情况下,如果动物的名称比较相等,(0-false),那么腿的数量将被计算以进行排序。

排序(排序后
{}
中的内容)定义了两层排序:首先按名称,然后按腿的数量。
实现了两个标准之间的交叉。如果代码的格式不同,则更容易查看:

@animals = sort {
    $animals{$a}{'name'} cmp $animals{$b}{'name'} or
    $animals{$a}{'legs'} <=> $animals{$b}{'legs'}
} keys %animals;
它不是很清楚,但因为它通常有更好的性能,所以它是一个常见的习惯用法。当比较的操作数是函数时,这一点尤为重要——这种技术可以防止每次比较都进行不必要的(可能代价高昂的)重新计算。例如,如果要按长度对字符串进行排序,则只需计算每个字符串的长度一次。

我可以建议作为当前代码的替代方案吗

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;
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;