我有一个包含 10 个数字的数组。我想在数组索引 0,2,4,6,8 中选择数字并将它们放入一个新数组中。索引 1,3,5,7,9 也是如此。我是 Perl 的新手(几天前开始)。
我的程序:
my @b;
@a = (1,2,3,4,5,6,7,8,9,10);
for($i=0;$i<=$#a;$i++)
{
push(@b,$a[$i+1]);
}
print "@b";
我究竟做错了什么?
我有一个包含 10 个数字的数组。我想在数组索引 0,2,4,6,8 中选择数字并将它们放入一个新数组中。索引 1,3,5,7,9 也是如此。我是 Perl 的新手(几天前开始)。
我的程序:
my @b;
@a = (1,2,3,4,5,6,7,8,9,10);
for($i=0;$i<=$#a;$i++)
{
push(@b,$a[$i+1]);
}
print "@b";
我究竟做错了什么?
我建议避免for
使用循环,因为在使用中更容易出错,并使用foreach
my @a = (1,2,3,4,5,6,7,8,9,10);
my (@even, @odd);
foreach my $i (0 .. $#a) {
if ($i % 2) { push @odd, $a[$i] } else { push @even, $a[$i] }
}
您还可以使用map
来测试数组索引模%
2,然后@even
决定过滤它()
或使用它取值$a[$_]
my @even = map { $_%2 ? () : $a[$_] } 0 .. $#a;
my @odd = map { $_%2 ? $a[$_] : () } 0 .. $#a;
简单的。
my @a = (1,2,3,4,5,6,7,8,9,10);
my (@even, @odd);
for ( @a ) {
$_ % 2 ? push @odd, $_ : push @even, $_;
}
一些东西:
use strict;
和use warnings;
. 这些会捕获很多错误。如果您使用,则必须使用(有时您会使用,但 99% 的情况下,您会使用)use strict;
声明您的变量my
our
my
for
循环中,您使用的是默认变量$_
。由于各种原因,这个变量是邪恶的。(一,它在范围内是全局的,所以其他东西可能会改变你的这个变量而你不会知道。)。声明您的变量,除非您必须使用$_
.{
一起。另一个是避免for 循环(并避免这只是 的别名)for
while
C style
foreach
for
$i <= $#a
得多$i<=$a
。这是我对您的程序的解释:
#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say); #A nicer 'print'
my @a = qw(12 13 14 15 16 17 18 19 20);
my @even;
my @odd;
for my $element (0..$#a) {
if ( $element % 2 ) {
push @odd, $a[$element];
}
else {
push @even, $a[$element];
}
}
say '@even = ' . join ': ', @even;
say '@odd = ' . join ': ', @odd;
输出:
@even = 12: 14: 16: 18: 20
@odd = 13: 15: 17: 19
for
循环。我使用0..$#a
来遍历数组的每个元素。is 返回数组的$#
最后一个索引。请注意,这比for($i=0;$i<=$#a;$i++)
您使用的更容易理解。这是不鼓励 C 风格的 for 循环的原因之一。%
来解析我的偶数/奇数。模数类似于余数除法。如果数字是奇数,则模数% 2
将为 1。否则,它为零。模运算非常适合在循环中工作的任何事物。但是让我们回到你的程序。这是您的原始代码,并进行了一些小的调整。
use strict;
and use warnings;
。这些可以捕获大约 99% 的编程错误。use feature qw(say);
因为say
在调试方面更好。我可以拿一个声明,复制它,然后把qq(...);
它扔到周围,看看它在做什么。say
语句来揭示代码的逻辑。让我们看看会发生什么。这是您的程序稍作修改:
#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
my @b;
my @a = (1,2,3,4,5,6,7,8,9,10);
my $i;
for($i=0; $i<=$#a; $i++) {
say "Index = $i Element = $a[$i + 1]";
say qq(push(\@b, $a[$i+1]););
push(@b,$a[$i+1]);
}
print "@b";
这是输出:
Index = 0 Element = 2
push(@b, 2);
Index = 1 Element = 3
push(@b, 3);
Index = 2 Element = 4
push(@b, 4);
Index = 3 Element = 5
push(@b, 5);
Index = 4 Element = 6
push(@b, 6);
Index = 5 Element = 7
push(@b, 7);
Index = 6 Element = 8
push(@b, 8);
Index = 7 Element = 9
push(@b, 9);
Index = 8 Element = 10
push(@b, 10);
Use of uninitialized value in concatenation (.) or string at ./test.pl line 11.
Index = 9 Element =
Use of uninitialized value within @a in concatenation (.) or string at ./test.pl line 12.
push(@b, );
Use of uninitialized value $b[9] in join or string at ./test.pl line 15.
我可以看到每个push
语句是如何执行的,并且看一下,您正在推动每个元素。其实,你并不是因为你把它$a[$i+1]
当做你在推动的东西。
使用use warnings
并且我可以看到我正在尝试将不存在的内容推$a[10]
送到您的@b
数组中。
让我们更改您的for
循环以转到其他所有元素
#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
my @b;
my @a = qw(1 2 3 4 5 6 7 8 9 10);
my $i;
for ($i=0; $i <= $#a; $i += 2) {
push @b, $a[$i];
}
第一个元素是$a[0]
。循环中的下一个元素是$a[2]
因为我添加2
了索引,而不是仅仅将它增加1
. 现在,我将遍历所有偶数元素并跳过所有奇数元素。
和输出:
1 3 5 7 9
(注意 $a[0] = 1。这就是为什么它们都是奇数。这就是我在12
程序中开始的原因,所以 $a[0] = 12 是偶数)。
我的偏好是使用while
并避免for(...; ...; ...)
构造:
#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
my @b;
my @a = qw(1 2 3 4 5 6 7 8 9 10);
my $i = 0;
while ( $i < $#a ) {
push @b, $a[$i];
$i += 2;
}
List::MoreUtils
有一个indexes
功能:
use List::MoreUtils qw{indexes} ;
use 5.10.0 ;
my @a = (1,2,3,4,5,6,7,8,9,10) ;
# index of array where even
say foreach indexes { $_ % 2 == 0 } @a ;
# index of array where odd
say foreach indexes { $_ % 2 != 0 } @a ;
我承认这可能有点不雅,在这里使用模块可能是作弊 - 尤其是不在 CORE 中的模块。如果List::MoreUtils
并且List::Utils
只是一个 CORE 模块会很方便,但仍然不如这里的其他一些答案那么优雅。
甚至:
for($i=0;$i<=$#a;$i+=2)
{
push(@b,$a[$i]);
}
奇怪的:
for($i=1;$i<=$#a;$i+=2)
{
push(@b,$a[$i]);
}