在perl中自动获取foreach循环中的循环索引

Nat*_*man 75 perl foreach

如果我在Perl中有以下数组:

@x = qw(a b c);
Run Code Online (Sandbox Code Playgroud)

然后我用它迭代它foreach,然后$_将引用数组中的当前元素:

foreach (@x) {
    print;
}
Run Code Online (Sandbox Code Playgroud)

将打印:

abc
Run Code Online (Sandbox Code Playgroud)

是否有类似的方法来获取当前元素的索引,而无需手动更新计数器?像这样的东西:

foreach (@x) {
    print $index;
}
Run Code Online (Sandbox Code Playgroud)

在哪里$index更新,$_以产生输出:

012
Run Code Online (Sandbox Code Playgroud)

tre*_*els 107

就像codehead所说的那样,你必须迭代数组索引而不是元素.我更喜欢这种变体而不是C风格的循环:

for my $i (0 .. $#x) {
    print "$i: $x[$i]\n";
}
Run Code Online (Sandbox Code Playgroud)

  • +1不使用丑陋的C风格for循环. (14认同)
  • 如果数组索引序列为2,5,8,19,并且序列中存在间隙,则这不是您想要的.我认为这个问题与当前元素的指数有关. (3认同)

Cha*_*ens 43

在5.10之前的Perl中,你可以说

#!/usr/bin/perl

use strict;
use warnings;

my @a = qw/a b c d e/;

my $index;
for my $elem (@a) {
    print "At index ", $index++, ", I saw $elem\n";
}

#or

for my $index (0 .. $#a) {
    print "At index $index I saw $a[$elem]\n";
}
Run Code Online (Sandbox Code Playgroud)

在Perl 5.10中,您使用state来声明一个永远不会重新初始化的变量(与使用my创建的变量不同).这允许您将$index变量保持在较小的范围内,但可能导致错误(如果您第二次进入循环,它仍将具有最后一个值):

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;

my @a = qw/a b c d e/;

for my $elem (@a) {
    state $index;
    say "At index ", $index++, ", I saw $elem";
}
Run Code Online (Sandbox Code Playgroud)

在Perl 5.12中你可以说

#!/usr/bin/perl

use 5.012; # This enables strict
use warnings;

my @a = qw/a b c d e/;

while (my ($index, $elem) = each @a) {
    say "At index $index I saw $elem";
}
Run Code Online (Sandbox Code Playgroud)

但要注意:你也有限制,你被允许用做什么@a,而遍历它each.

它现在对你没有帮助,但在Perl 6中你可以说

#!/usr/bin/perl6

my @a = <a b c d e>;
for @a Z 0 .. Inf -> $elem, $index {
    say "at index $index, I saw $elem"
}
Run Code Online (Sandbox Code Playgroud)

所述Z操作者的两个列表拉链一起(即,它需要一个元件从第一清单中,然后从第二一个元件,再一个元件从第一,依此类推).第二个列表是一个惰性列表,其中包含从0到无穷大的每个整数(至少在理论上).该-> $elem, $index说,我们正处在一个时间从zip的结果取两个值.其余的应该看起来很正常(除非你不熟悉say5.10中的功能).


Ala*_*avi 22

perldoc perlvar 似乎没有暗示任何这样的变数.

  • -1.这完全违背了Stackoverflow的精神. (10认同)
  • [*AndrewKS*](http://stackoverflow.com/users/444794/andrewks):这肯定不符合StackOverflow的精神.如果你曾经尝试过`perldoc perlvar`,你会知道为什么.只存在`perldoc perlvar`中列出的变量.正如我已经说过的那样,这样的变量不存在. (5认同)
  • 这**违背了stackoverflow的精神,因为精神是提供一个答案,可以在没有外部资源的情况下完整地回答问题.提供可选资源(例如链接或终端命令)来运行学习是一个奖励,但不是*精神*.您必须在评论中提供更多信息这一事实证明,这个答案本身并不足够. (5认同)

cod*_*ead 8

不是foreach.如果你肯定需要数组中的元素基数,请使用'for'迭代器.

for ($i=0; $i<@x; ++$i) {
  print "Element at index $i is " , $x[$i] , "\n";
}
Run Code Online (Sandbox Code Playgroud)

  • 引自'perldoc perlvar':"foreach"关键字实际上是"for"关键字的同义词,因此您可以将"foreach"用于可读性或"for"用于简洁.endquote.所以他们*是可以互换的.试试吧. (9认同)
  • foreach和for是可互换的同义词.一些介绍性材料试图用于表示列表迭代器循环的C风格循环和foreach,但是术语的使用并不是每个人都熟悉的. (5认同)
  • 一个C风格的循环(你们都继续调用"for循环")不必增加/减少一个变量,例如:for(my $ iter = new_iter(); $ iter; $ iter = $ iter - > next()){...} (3认同)
  • 如该实例所示,foreach和for是/ not /可互换的。 (2认同)

Ven*_*aju 7

Perl版本 while

可以用foreach循环完成(while不支持这个)

my @arr = (1111, 2222, 3333);

while (my ($index, $element) = each(@arr))
{
   # You may need to "use feature 'say';"
   say "Index: $index, Element: $element";
}
Run Code Online (Sandbox Code Playgroud)

输出:

Index: 0, Element: 1111
Index: 1, Element: 2222
Index: 2, Element: 3333
Run Code Online (Sandbox Code Playgroud)


Hyn*_*dil 5

不,您必须创建自己的柜台。又一个例子:

my $index;
foreach (@x) {
    print $index++;
}
Run Code Online (Sandbox Code Playgroud)

用于索引时

my $index;
foreach (@x) {
    print $x[$index]+$y[$index];
    $index++;
}
Run Code Online (Sandbox Code Playgroud)

当然,您可以使用等等local $index;代替my $index;