如果我在Perl中有以下数组:
@x = qw(a b c);
然后使用进行遍历foreach
,然后$_
引用数组中的当前元素:
foreach (@x) {
print;
}
将打印:
abc
是否有类似的方法来获取当前元素的索引,而无需手动更新计数器?如:
foreach (@x) {
print $index;
}
在哪里$index
更新$_
以产生输出:
012
如果我在Perl中有以下数组:
@x = qw(a b c);
然后使用进行遍历foreach
,然后$_
引用数组中的当前元素:
foreach (@x) {
print;
}
将打印:
abc
是否有类似的方法来获取当前元素的索引,而无需手动更新计数器?如:
foreach (@x) {
print $index;
}
在哪里$index
更新$_
以产生输出:
012
Answers:
就像codehead所说的那样,您必须遍历数组索引而不是其元素。我更喜欢这种变体而不是C风格的for
循环:
for my $i (0 .. $#x) {
print "$i: $x[$i]\n";
}
next unless defined $x[$i];
在循环的开头放置一行。对于涉及while / each和for / key的所有更具风险的解决方案,这似乎也是正确的。显然,数组迭代器会查看每个顺序索引是否存在。
$x[$i] // next;
在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
它现在对您无济于事,但是在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"
}
所述Z
操作者的两个列表拉链一起(即,它需要一个元件从第一清单中,然后从第二一种元素,然后从第一,依此类推一种元素)。第二个列表是一个惰性列表,其中包含从0到无穷大的每个整数(至少在理论上是这样)。该-> $elem, $index
说,我们正处在一个时间从zip的结果取两个值。其余的看起来对您来说是正常的(除非您对say
5.10版的功能还不熟悉)。
state
,我认为最好与它搭配使用{ my $index; ... }
。
perldoc perlvar
似乎没有建议任何此类变量。
perldoc perlvar
,您会知道为什么。仅perldoc perlvar
存在列出的变量。正如我已经说过的,这种变量不存在。
不与foreach
。
如果您确实需要数组中的元素基数,请使用“ for”迭代器:
for ($i=0; $i<@x; ++$i) {
print "Element at index $i is " , $x[$i] , "\n";
}
可以通过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
Perl版本:5.14.4
不,您必须创建自己的柜台。又一个例子:
my $index;
foreach (@x) {
print $index++;
}
用于索引时
my $index;
foreach (@x) {
print $x[$index]+$y[$index];
$index++;
}
当然,您可以使用等等local $index;
代替my $index;
。
for
循环语法更具可读性。for(my $index; $index <= $#x; $index++){}
。
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;
}
另请参阅:
哦,可以!(有点,但您不应该)。each(@array)
标量上下文中的值可为您提供数组的当前索引。
@a = (a..z);
for (@a) {
print each(@a) . "\t" . $_ . "\n";
}
这each(@a)
是在标量上下文中,并且仅返回索引,而不返回该索引处的值。由于我们处于for
循环中,因此我们已经在$ _中拥有了值。在while-each循环中经常使用相同的机制。同样的问题。
如果您再做for(@a)
一次,问题就来了。索引没有回到您期望的0;它undef
随后0,1,2 ......一个报数。的perldoceach()
说避免了这个问题。使用for
循环来跟踪索引。
基本上:
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++;
}
each(@a)
在循环中再次使用的意思,例如print each(@a)."=< $_ >=".each(@a);
。
好吧,这是这样的:
use List::Rubyish;
$list = List::Rubyish->new( [ qw<a b c> ] );
$list->each_index( sub { say "\$_=$_" } );
我尝试过...
@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 the 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;