下面的代码完成了我想要的.它打印列表并在不连续的行的末尾添加星号,例如,如果您从1跳到3或从3跳到5.
use strict;
use warnings;
#note: thanks to all who helped with formatting issues.
#note: I recognize a hash would be a much better option for what I want to do.
my @printy = ("1 -> this",
"5 -> that",
"3 -> the other",
"6 -> thus and such");
@printy = sort {num($a) <=> num($b)} @printy;
my $thisID = 0;
my $lastID = 0;
#print out (line)* if initial number is >1 more than previous, or just (line) otherwise
for (@printy)
{
$thisID = $_; $thisID =~s/ .*//g;
if ($thisID - $lastID != 1) { $_ =~ s/$/ \*/; }
$lastID = $thisID;
}
print join("\n", @printy) . "\n";
sub num
{
my $x = $_[0];
$x =~ s/ .*//;
return $x;
}
Run Code Online (Sandbox Code Playgroud)
但我认为我可以做得更好.感觉很纠结,我的直觉告诉我,我错过了一些能够更容易完成工作的强大功能,可能需要两行.
现在我以前使用过该map()命令,但只是查看/修改一个元素,而不是它与前一个元素的比较.任何人都可以推荐一种方法来使这更简洁吗?谢谢!
由于Perl推广TIMTOWTDI,起初map看起来似乎是一个很有吸引力的选择.让我们看看它如何为这项任务付出代价:
由于访问相邻元素是必要的,因此使用索引很方便.因为对于n元素,有n-1成对的邻居,你不必循环n时间.在这种情况下,让我们从1通常开始0:
1 .. $#printy
Run Code Online (Sandbox Code Playgroud)可以通过调用内部的相关索引来访问相邻元素map.
map { my $prev = $printy[$_-1]; my $curr = $printy[$_] } 1 .. $#printy;
Run Code Online (Sandbox Code Playgroud)
数组切片更简洁地表达了这一点:
map { my ( $prev, $curr ) = @printy[$_-1,$_]; } 1 .. $#printy;
Run Code Online (Sandbox Code Playgroud)让我们介绍使用num子程序比较数字的真实逻辑:
map {
my ( $prev, $curr ) = @printy[$_-1,$_];
if ( num($curr) - num($prev) > 1 ) {
"$curr *";
}
else {
$curr;
}
} 1 .. $#printy;
Run Code Online (Sandbox Code Playgroud)
这相当于:
map {
my ( $prev, $curr ) = @printy[$_-1,$_];
$curr .= " *" if num($curr) - num($prev) > 1;
$curr
} 1 .. $#printy;
Run Code Online (Sandbox Code Playgroud)记住不要忘记第一个元素:
@printy = ( $printy[0],
map {
my ( $prev, $curr ) = @printy[$_-1,$_];
$curr .= " *" if num($curr) - num($prev) > 1;
$curr
} 1 .. $#printy
);
Run Code Online (Sandbox Code Playgroud)鉴于最终结果,我不太确定我会用到map这个: