我想比较2个连续的循环元素
@arr=qw(1 2 3 3 4);
foreach(@arr)
{
if($_ == $_+1)
{
print "yes";
}
}
在这种情况下,我应该使用什么而不是$ _ + 1
答案 0 :(得分:5)
你必须循环索引,
my @arr = qw(1 2 3 3 4);
foreach (0 .. $#arr-1) {
my ($current, $next) = @arr[$_, $_+1];
if ($current == $next) {
print "yes";
}
}
答案 1 :(得分:1)
我会用简单的老C方式做到这一点:
for( my $i=0; $i<@arr-1; $i++ ){
if( $arr[$i] == $arr[$i+1] ){
print "yes\n";
}
}
或者是另一种风格:
print "Yes\n" for grep{ $arr[$_] == $arr[$_+1] }(0..$#arr-1);
答案 2 :(得分:0)
FP解决方案将使用pairwise
中的List::MoreUtils
:
pairwise {
say "yes" if $a == $b;
} @arr @{[ @arr[1..$#arr] ]}
(@{[ ... ]}
很烦人,但是pairwise
需要一个真正的数组,并且数组切片不是(你不能引用它们)。)
(注意:$b
将在数组的最后一次迭代中未定义,这可能是你想要的。)
答案 3 :(得分:0)
是的,可以使用基于范围的foreach
循环执行此操作,而无需处理索引。但是,不要向前看,而是要跟踪你去过的地方;您在上一次迭代中获得的数字。并且在第一次迭代时避免使用print
。
{
my $prev;
foreach ( @arr ) {
print "yes ($prev==$_)\n" if defined $prev && $prev == $_;
$prev = $_;
}
}
这假设@arr
中没有'undef'元素。如果可能的话,使用不同的标记来检测第一次迭代,或者只是迭代索引,如其他答案所示。
如果您的循环使用next
,您可能希望在每次迭代结束时将绝对必须发生的事情放入continue{...}
块。
{
my $prev;
foreach ( @arr ) {
next unless defined $prev && $prev == $_;
print "yes ($prev==$_)\n";
}
continue {
$prev = $_;
}
}
外部区块不是严格必要的;它只是用来约束我们临时$prev
变量的范围。
请记住,使用Perl时,仅仅访问数组中的元素可能会产生副作用(感谢绑定变量的魔力)。因此foreach
提供“peek_next”功能并不一定是一个好主意(从语言设计的角度来看)。