mle*_*amp 3 sorting perl cmp lexicographic
我看到以下代码的结果,但我不明白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);
Run Code Online (Sandbox Code Playgroud)
Mic*_*man 14
所述sortsub(在东西{}后sort)定义两层排序:第一按名称,然后通过腿的数.在or实现了两个标准之间的交叉.您可以更轻松地查看是否以不同方式格式化代码:
@animals = sort {
$animals{$a}{'name'} cmp $animals{$b}{'name'} or
$animals{$a}{'legs'} <=> $animals{$b}{'legs'}
} keys %animals;
Run Code Online (Sandbox Code Playgroud)
的cmp和<=>运营商返回的三个值(-1,0或1),这取决于左边参数是否大于右参数小于,等于或大于中的一个.(cmp做一个字符串比较,<=>做一个数字.)在Perl中,0为假,而-1和1为真.如果cmp返回true值,则or立即返回该值,并sort相应地重新排序元素.如果cmp返回false,<=>则评估并返回其结果.
在进行多层排序时,通常使用"map-sort-map"技术(又名Schwartzian变换):
@animals =
map { $_->[0] }
sort {
$a->[1] cmp $b->[1] ||
$a->[2] <=> $b->[2]
}
map { [$_, $animal{$_}{name}, $animal{$_}{legs}] }
keys %animal;
Run Code Online (Sandbox Code Playgroud)
它不是那么清楚,但因为它通常具有更好的性能,所以它是一种常见的习语.当比较的操作数是函数时,这一点尤为重要 - 这种技术可以防止每次比较的不必要(并且可能是昂贵的)重新计算.例如,如果您按长度排序字符串,则只需计算一次字符串的长度.
or 是一个短路评估器,因此它将返回左侧的值,如果它是真的(这是任何非零值),否则将评估右侧.
因此,在这种情况下,如果动物的名字相等,(0 - 假),腿数将被计算用于分类目的.