我有一个包含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";
我做错了什么?
答案 0 :(得分:2)
我建议避免使用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[$_]
为它取值1}}
my @even = map { $_%2 ? () : $a[$_] } 0 .. $#a;
my @odd = map { $_%2 ? $a[$_] : () } 0 .. $#a;
答案 1 :(得分:2)
简单。
my @a = (1,2,3,4,5,6,7,8,9,10);
my (@even, @odd);
for ( @a ) {
$_ % 2 ? push @odd, $_ : push @even, $_;
}
答案 2 :(得分:1)
偶:
for($i=0;$i<=$#a;$i+=2)
{
push(@b,$a[$i]);
}
奇:
for($i=1;$i<=$#a;$i+=2)
{
push(@b,$a[$i]);
}
答案 3 :(得分:1)
一些事情:
use strict;
和use warnings;
。这些会遇到很多错误。如果您使用use strict;
,则必须使用my
声明变量(有时您会使用our
,但99%的情况下,您将使用my
})for
循环中,您使用的是默认变量$_
。由于各种原因,这个变量是邪恶的。 (一,它在全球范围内,所以其他东西可以改变你的变量,你不会知道。)。声明您的变量,除非您必须使用$_
。{
放在for
和while
的行上。另一种方法是避免C style
for循环(并避免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
遍历数组的每个元素。 $#
返回数组的最后一个索引。请注意,这比您使用的for($i=0;$i<=$#a;$i++)
更容易理解。这是为什么不鼓励使用C风格循环的原因之一。%
来解析偶数/奇数。 Modulo就像剩余部门。如果数字是奇数,则模% 2
将为1.否则,它为零。模数运算对于在循环中工作的任何事物都很有用。 但是让我们回到你的计划。这是您的原始代码,稍作调整。
use strict;
和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;
}
答案 4 :(得分:1)
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模块会很方便,但仍然不像其他答案那样优雅。