按字典顺序排序
我看到以下代码的结果,但我不明白 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);
I see the results from the following code, but I don't understand exactly how the or
knows what to do in the following sort
example:
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);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
sortsub(
{}
中sort
之后的内容)定义了两层排序:首先按名称排序,然后按分支数排序。or
实现了两个标准之间的交叉。 如果您以不同的方式设置代码格式,则更容易查看:cmp
和<=>
运算符返回三个值之一(-1、0 或 1),具体取决于左参数是否小于、等于或大于右参数。 (cmp
进行字符串比较,<=>
进行数字比较。)在 Perl 中,0 为 false,而 -1 和 1 为 true。 如果cmp
返回真值,or
立即返回该值,并且sort
适当地重新排序元素。 如果cmp
返回 false,则会评估<=>
并返回其结果。在进行多层排序时,通常使用“map-sort-map”技术(又名 Schwartzian Transform ):
不太清楚,但因为它通常具有更好的性能,所以它是一个常见的习惯用法。 当比较的操作数是函数时,这一点尤其重要——这种技术可以防止每次比较时不必要的(并且可能昂贵的)重新计算。 例如,如果您按长度对字符串进行排序,则只需计算每个字符串的长度一次。
The sortsub (the stuff in
{}
after thesort
) defines a two-tier sort: first by name, then by number of legs. Theor
implements the cross-over between the two criteria. It's easier to see if you format the code differently:The
cmp
and<=>
operators return one of three values (-1, 0, or 1) depending on whether the left argument is less than, equal to, or greater than the right argument. (cmp
does a string comparison,<=>
does a numeric one.) In Perl, 0 is false while -1 and 1 are true. If thecmp
returns a true value, theor
returns that value immediately, andsort
reorders the elements appropriately. If thecmp
returns false, the<=>
is evaluated and its result is returned instead.When doing multi-layer sorts, it's common to use a "map-sort-map" technique (a.k.a. Schwartzian Transform):
It's not as clear but because it usually has better performance it's a common idiom. This is especially important when the operands to the comparison are functions -- this technique prevents an unnecessary (and possibly expensive) recalculation for every comparison. For example, if you're sorting strings by length you only need to compute the length of each string once.
or
是一个短路求值器,因此如果为真(任何非零值),它将返回左侧的值,否则将计算右侧的值。因此,在这种情况下,如果动物的名称比较相等(0 - false),则将计算腿的数量以进行排序。
or
is a short-circuit evaluator, so it will return the value of the left-hand side if it's true (which is any non-zero value), and otherwise will evaluate the right-hand side.So in this case, if the animals' names compare as equal, (0 - false), the number of legs will be counted for sorting purposes.
我可以建议
Sort::Key
作为当前代码的替代方案?May I suggest
Sort::Key
as an alternative for the present code altogether?