从数组中选择元素并将其放入Perl中的另一个数组中

时间:2013-06-12 21:06:38

标签: perl

我有一个包含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";

我做错了什么?

5 个答案:

答案 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循环中,您使用的是默认变量$_。由于各种原因,这个变量是邪恶的。 (一,它在全球范围内,所以其他东西可以改变你的变量,你不会知道。)。声明您的变量,除非您必须使用$_
  • 标准是将{放在forwhile的行上。另一种方法是避免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::MoreUtilsList::Utils只是一个CORE模块会很方便,但仍然不像其他答案那样优雅。