我今天开始学习Perl并发现了这个非常有趣的教程.但是,对于我的生活,我无法绕过这段代码.
print " $_: $created{$_}" for(sort({$created{$b} <=> $created{$a}} keys %created));
Run Code Online (Sandbox Code Playgroud)
这是什么类型的?更具体地讲,什么是变量$a和$b?我试过浏览文档,但不能说它有帮助.任何支持将不胜感激.
这里发生了一些事情.首先,我将解决后缀循环;
say $_ for ('foo', 'bar', 'baz');
Run Code Online (Sandbox Code Playgroud)
这在语义上与执行此操作相同
for ('foo', 'bar', 'baz') { say $_ }
Run Code Online (Sandbox Code Playgroud)
现在进行排序.默认情况下,Perl sort按字母顺序排序
sort (20, 3, 100); # RESULT: (100, 20, 3)
Run Code Online (Sandbox Code Playgroud)
Perl提供了一种按字母顺序(cmp)或数字(<=>)显式比较的方法.
20 cmp 3; # RESULT: -1 (means: Less)
20 <=> 3; # RESULT: 1 (means: More)
20 <=> 20; # RESULT: 0 (means: Same)
Run Code Online (Sandbox Code Playgroud)
所以你可以在一个sort块中使用这些运算符,但是你把它放在运算符的哪一边?这是特殊$a和$b变量的来源.
sort { $a <=> $b } (20, 3, 100); # RESULT: (3, 20, 100)
Run Code Online (Sandbox Code Playgroud)
这也是为什么你不应该手动分配值,$a或者$b如果你这样做,sort将无法正常运行!
所以把它们放在一起,你的排序是按照数字对应的值对Hash的键进行排序
my %hash = ( twenty => 20, three => 3, onehundred => 100 );
for ( sort { $hash{$a} <=> $hash{$b} } keys %hash ) {
say "$_: %hash{$_}"
}
Run Code Online (Sandbox Code Playgroud)
输出
three: 3
twenty: 20
onehundred: 100
Run Code Online (Sandbox Code Playgroud)
您也可以{ $b <=> $a }反向排序.
如果这一切看起来晦涩难懂,那就有点儿了.我建议使用类似于Sort::Key大多数排序需求的模块......或者Sort::Naturally如果那更像你所追求的那样.
print " $_: $created{$_}"
for ( sort { created{$b} <=> $created{$a} } keys %created );
Run Code Online (Sandbox Code Playgroud)
这使用了后修复形式for.在Perl,for并且foreach是相同的.两者都可以与C风格的for语法以及较短的foreach样式语法一起使用.
我们可以将此循环重写为以下更详细的版本.
foreach ( sort { created{$b} <=> $created{$a} } keys %created ) {
print " $_: $created{$_}";
}
Run Code Online (Sandbox Code Playgroud)
接下来,我们来看看$_.它被称为主题,如果没有给出其他变量,它将被用作Perl中很多东西的默认输入.在foreach循环中,如果没有使用迭代变量,则括号中列表的每个元素都会结束$_.同样,为了清楚起见,可以重写.
foreach my $elem ( sort { created{$b} <=> $created{$a} } keys %created ) {
print " $elem: $created{$elem}";
}
Run Code Online (Sandbox Code Playgroud)
现在让我们来看看sort.这两个变量$a,并$b在全局变量总是在那里Perl编写的.它们是为sort语句后面的块保留的.
sort { BLOCK } LIST
Run Code Online (Sandbox Code Playgroud)
$a并$b包含列表中的两个值,这些值在块中进行比较.该块的行为类似于匿名函数(在其他语言中称为lambda),并且后面没有逗号.或者,您可以将名称sub的名称作为带有引号的裸字放在那里.再说一遍,没有逗号.
sub bubbly_sort { $a <=> $b }
sort bubbly_sort 3, 2, 1;
Run Code Online (Sandbox Code Playgroud)
该<=>运营商做数值比较.这两个值和收益进行比较-1,0或1.
sort { $b <=> $a } LIST
Run Code Online (Sandbox Code Playgroud)
这将对LIST中的值进行数字降序排序,因此最高值首先出现.$a <=> $b会提升.
sort { created{$b} <=> $created{$a} } keys %created
Run Code Online (Sandbox Code Playgroud)
该keys关键字为您提供散列内的密钥的无序列表%created.您在块中的块sort比较%created哈希中这些键后面的值,并对键降序进行排序.所以你得到一个排序键列表.
其余代码只打印出该排序键列表的键/值列表.
值得注意的是,输出全部在一行上,因为之后没有换行符print.
您发布的精简版本比我在此答案中显示的长版本更具可读性.但它有适当的缩进和括号的使用.
print " $_: $created{$_}"
for sort { created{$b} <=> $created{$a} } keys %created;
Run Code Online (Sandbox Code Playgroud)
与
print " $_: $created{$_}" for(sort({$created{$b} <=> $created{$a}} keys %created));
Run Code Online (Sandbox Code Playgroud)
与
foreach ( sort { created{$b} <=> $created{$a} } keys %created ) {
print " $_: $created{$_}";
}
Run Code Online (Sandbox Code Playgroud)
在我看来,第一个版本读起来最像英语句子,这很好.干净,可读的代码应始终是优秀开发人员的首要任务.