下面的代码实现了我想要的功能。它打印列表并在不连续的行末尾添加一个星号,例如如果您从 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;
}
但我认为我可以做得更好。感觉很困惑,我的直觉告诉我,我错过了一些强大的东西,可以更轻松地完成这项工作,一个可能需要两行的东西。
现在我之前使用过 map()
命令,但只是为了查看/修改一个元素,而不是它与前一个元素的比较。任何人都可以推荐一种方法来使其更加简洁吗?谢谢!
最佳答案
由于 Perl 推广 TIMTOWTDI,map
乍一看似乎是一个有吸引力的选择。让我们看看这个任务的表现如何:
施瓦茨思维过程
由于需要访问相邻元素,因此使用索引很方便。由于对于
n
个元素,有n-1
对邻居,因此您不必循环n
次。在本例中,我们从1
开始,而不是通常的0
:1 .. $#printy
可以通过调用
map
内的相关索引来访问相邻元素。map { my $prev = $printy[$_-1]; my $curr = $printy[$_] } 1 .. $#printy;
数组切片更简洁地表达了这一点:
map { my ( $prev, $curr ) = @printy[$_-1,$_]; } 1 .. $#printy;
让我们介绍一下使用
num
子例程比较数字的实际逻辑:map { my ( $prev, $curr ) = @printy[$_-1,$_]; if ( num($curr) - num($prev) > 1 ) { "$curr *"; } else { $curr; } } 1 .. $#printy;
这相当于:
map { my ( $prev, $curr ) = @printy[$_-1,$_]; $curr .= " *" if num($curr) - num($prev) > 1; $curr } 1 .. $#printy;
记住不要忘记第一个元素:
@printy = ( $printy[0], map { my ( $prev, $curr ) = @printy[$_-1,$_]; $curr .= " *" if num($curr) - num($prev) > 1; $curr } 1 .. $#printy );
鉴于最终结果,我不太确定是否会使用 map
来实现此目的:
- 很难读
- 发生了很多事情
- 下一个处理您代码的人会喜欢您
关于perl - 我怎样才能使用map来清理这个Perl代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40997876/