如果我在Perl中有以下数组:
@x = qw(a b c);
我用foreach
迭代它,然后$_
将引用数组中的当前元素:
foreach (@x) {
print;
}
将打印:
abc
是否有类似的方法来获取当前元素的索引,而无需手动更新计数器?例如:
foreach (@x) {
print $index;
}
其中$index
更新为$_
以产生输出:
012
答案 0 :(得分:102)
就像codehead所说的那样,你必须迭代数组索引而不是它的元素。我更喜欢这种变体而不是C风格的循环:
for my $i (0 .. $#x) {
print "$i: $x[$i]\n";
}
答案 1 :(得分:42)
在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";
}
在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";
}
在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";
}
但请注意:@a
在使用each
进行迭代时,#!/usr/bin/perl6
my @a = <a b c d e>;
for @a Z 0 .. Inf -> $elem, $index {
say "at index $index, I saw $elem"
}
允许您使用restrictions。{/ p>
现在对你没有帮助,但在Perl 6中你可以说
Z
-> $elem, $index
运算符将两个列表压缩在一起(即,它从第一个列表中获取一个元素,然后从第二个列表中获取一个元素,然后从第一个中获取一个元素,依此类推)。第二个列表是lazy列表,其中包含从0到无穷大的每个整数(至少在理论上)。 {{1}}表示我们从zip结果中一次取两个值。其余的应该看起来很正常(除非你不熟悉5.10中的say
函数)。
答案 2 :(得分:23)
perldoc perlvar
似乎没有暗示任何此类变量。
答案 3 :(得分:7)
不是foreach。 如果你肯定需要数组中的元素基数,请使用'for'迭代器。
for($i=0;$i<@x;++$i) {
print "Element at index $i is ",$x[$i],"\n";
}
答案 4 :(得分:6)
Perl版本5.14.4
可以使用while
循环完成(foreach
不支持此操作)
my @arr = (1111, 2222, 3333);
while (my ($index, $element) = each(@arr))
{
# You may need to "use feature 'say';"
say "Index: $index, Element: $element";
}
输出:
Index: 0, Element: 1111
Index: 1, Element: 2222
Index: 2, Element: 3333
答案 5 :(得分:4)
不,你必须自己制作一个柜台。又一个例子:
my $index;
foreach (@x) {
print $index++;
}
用于索引
my $index;
foreach (@x) {
print $x[$index]+$y[$index];
$index++;
}
当然,您可以使用local $index;
代替my $index;
等等。
编辑:根据第一个ysth的评论更新。
答案 6 :(得分:4)
是。我检查过这么多书和其他博客......结论是,循环计数器没有系统变量。我们要做自己的柜台。如果我错了,请纠正我。
答案 7 :(得分:2)
autobox::Core
提供了许多方便的for
方法:
use autobox::Core;
['a'..'z']->for( sub{
my ($index, $value) = @_;
say "$index => $value";
});
或者看一下迭代器模块,例如:Array::Iterator
use Array::Iterator;
my $iter = Array::Iterator->new( ['a'..'z'] );
while ($iter->hasNext) {
$iter->getNext;
say $iter->currentIndex . ' => ' . $iter->current;
}
另见:
/ I3az /
答案 8 :(得分:1)
有这样的方式:
use List::Rubyish;
$list = List::Rubyish->new( [ qw<a b c> ] );
$list->each_index( sub { say "\$_=$_" } );
答案 9 :(得分:1)
哦,可以! (有点,但您不应该)。标量上下文中的each(@array)
为您提供数组的当前索引。
@a = (a..z);
for (@a){
print each(@a) . "\t" . $_ . "\n";
}
此处each(@a)
在标量上下文中,仅返回索引,而不返回该索引处的值。由于我们处于for循环中,因此我们已经在$ _中拥有了值。 While-Each循环中经常使用相同的机制。同样的问题。
如果再次执行for(@a)
,问题就来了,索引没有回到您期望的0,它是undef
后跟0,1,2 ...一个数字。 each()
的perldoc表示为避免此问题,请使用for
循环来跟踪索引。 https://perldoc.perl.org/functions/each.html
基本上:
for(my $i=0; $i<=$#a; $i++){
print "The Element at $i is $a[$i]\n";
}
我是替代方法的粉丝
my $index=0;
for (@a){
print "The Element at $index is $a[$index]\n";
$index++;
}
答案 10 :(得分:0)
在大多数情况下你不需要知道索引,你可以这样做
my @arr = (1, 2, 3);
foreach (@arr) {
$_++;
}
print join(", ", @arr);
在这种情况下,输出将是 2,3,4 ,因为foreach为实际元素设置别名,而不仅仅是副本。
答案 11 :(得分:0)
我试过......
@array = qw /tomato banana papaya potato/; # example array
my $count; # local variable initial value will be 0
print "\nBefore For loop value of counter is $count"; # just printing value before entering in loop
for (@array) { print "\n",$count++," $_" ; } # string and variable seperated by comma to
# execute the value and print
undef $count; # undefining so that later parts again it will
# be reset to 0
print "\nAfter for loop value of counter is $count"; # checking the counter value after for loop.
简而言之..
@array = qw /a b c d/;
my $count;
for (@array) { print "\n",$count++," $_"; }
undef $count;
答案 12 :(得分:0)
请考虑:
print "Element at index $_ is $x[$_]\n" for keys @x;