Ant*_*rks 2 arrays perl foreach for-loop shift
希望在shift函数@_内部的数组上使用该函数,以便该函数可以接受可变数量的参数。根据 L Wall 等人在“Programming Perl”中的 p112,传递给子例程的参数被连接成一个平面数组,即@_。假设可以使用shift函数或foreach循环遍历此数组以确定传递的所有值中的最小值,即使某些参数本身就是数组并且这些值作为元素包含在这些数组中。
尝试了许多变体,并且 min2 和 min4 变体使用“for each”循环(最接近“Programming Perl”的 p113 上的循环)来遍历 @_ 数组。使用“shift”函数遍历@_ 数组的 min1 和 min3 变体确实正常工作。关于是什么导致基于“shift”功能的变体失败的任何想法?
下面给出了四个“min”子程序:
# Using perl5.14.2.exe
use strict;
sub min {
my $m=shift @_;
my $b;
while ($b = shift @_){
if ($b < $m) {$m=$b};
};
return $m;
};
sub min_v2 {
my $m = $_[0];
foreach (@_){
if ($_ < $m) {$m = $_};
};
return $m;
};
sub min_v3 {
my $m=shift (@_);
my $b;
while ($b = shift (@_)){
if ($b < $m) {$m=$b};
};
return $m;
};
sub min_v4 {
# Similar to Programming Perl 2nd Ed by Larry Wall et al p113
my $m=shift (@_);
foreach $b (@_){
if ($b < $m) {$m=$b};
};
return $m;
};
Run Code Online (Sandbox Code Playgroud)
以下代码用于测试例程:
print 'min 10,50,5,1 = ' , min (10,50,5,1 ), "\n" ;
print 'min ((10,50,5),1) = ' , min ((10,50,5),1) , "\n" ;
print 'min ((10,50,0),1) = ' , min ((10,50,0),1) , "\n" ;
print 'min (30,0) = ', min (30,0), "\n";
print 'min_v2 (30,0) = ', min_v2 (30,0), "\n";
print 'min_v3 (30,0) = ', min_v3 (30,0), "\n";
print 'min_v4 (30,0) = ', min_v4 (30,0), "\n";
my @a;
@a = (1,2,3,30);
print '@a = ' , "[ @a ]" , , "\n";
print 'min (@a,0) = ' , min (@a,0) , "\n";
print 'min_v2 (@a,0) = ' , min_v2 (@a,0) , "\n" ;
print 'min_v3 (@a,0) = ' , min_v3 (@a,0) , "\n" ;
print 'min_v4 (@a,0) = ' , min_v4 (@a,0) , "\n" ;
@a = (3,2,1,30);
print '@a = ' , "[ @a ]" , , "\n";
print 'min (@a,0) = ' , min (@a,0) , "\n";
print 'min_v2 (@a,0) = ' , min_v2 (@a,0) , "\n" ;
print 'min_v3 (@a,0) = ' , min_v3 (@a,0) , "\n" ;
print 'min_v4 (@a,0) = ' , min_v4 (@a,0) , "\n" ;
@a = (3,2,1,30);
print '@a = ' , "[ @a ]" , , "\n";
print 'min (@a,2) = ' , min (@a,2) , "\n";
print 'min_v2 (@a,2) = ' , min_v2 (@a,2) , "\n" ;
print 'min_v3 (@a,2) = ' , min_v3 (@a,2) , "\n" ;
print 'min_v4 (@a,2) = ' , min_v4 (@a,2) , "\n" ;
Run Code Online (Sandbox Code Playgroud)
并生成了以下输出:
min 10,50,5,1 = 1
min ((10,50,5),1) = 1
min ((10,50,0),1) = 10
min (30,0) = 30
min_v2 (30,0) = 0
min_v3 (30,0) = 30
min_v4 (30,0) = 0
@a = [ 1 2 3 30 ]
min (@a,0) = 1
min_v2 (@a,0) = 0
min_v3 (@a,0) = 1
min_v4 (@a,0) = 0
@a = [ 3 2 1 30 ]
min (@a,0) = 1
min_v2 (@a,0) = 0
min_v3 (@a,0) = 1
min_v4 (@a,0) = 0
@a = [ 3 2 1 30 ]
min (@a,2) = 1
min_v2 (@a,2) = 1
min_v3 (@a,2) = 1
min_v4 (@a,2) = 1
Run Code Online (Sandbox Code Playgroud)
问题与shift或无关@_。问题在于,当您0从列表中移动值时,while条件评估为 false,并且循环在您预期之前终止。考虑这个更简单的例子:
use warnings;
use strict;
my @nums = (50, 30, 0, 1);
my $m = 10;
my $b;
while ($b = shift @nums) {
print "b=$b m=$m\n";
if ($b < $m) {$m=$b}
}
print "m=$m\n";
Run Code Online (Sandbox Code Playgroud)
输出:
b=50 m=10
b=30 m=10
m=10
Run Code Online (Sandbox Code Playgroud)
数组 (50, 30) 中的 1st 2 个值的行为符合预期。一旦0从数组中移动 ,循环就结束。