PERL for循环中$ _的下一个元素是什么

时间:2014-11-20 15:28:19

标签: perl

我想比较2个连续的循环元素

@arr=qw(1 2 3 3 4);
foreach(@arr)
{
if($_ == $_+1)
  {
  print "yes";
  }
}

在这种情况下,我应该使用什么而不是$ _ + 1

4 个答案:

答案 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”功能并不一定是一个好主意(从语言设计的角度来看)。