Perl - 从2个相等长度的数组构建2D数组

时间:2013-06-20 23:47:07

标签: perl

所以我应该先说这个我已经解决了这个问题,但语法很糟糕,所以我想看看是否有一种Perl-ish方式做得更好。

我有两个长度为n的数组(@genes@names)。我想将它们组合成一个配对值的2D数组。

我现在的做法是;

$Num = Number of elements in each array

my @genes = ();
foreach my $i ( 0 .. $num-1 ) {
    foreach my $j ( 0 .. 1 ) {
    if ($j == 0){ push @{ $genes[$i] }, $names[$i];}
    if ($j == 1){ push @{ $genes[$i] }, $lengths[$i];}
    }
}

但是这需要为每个附加列提供一个显式行(现在我有两个 - 名称和长度)。它也很可怕。只有母亲可以爱的代码。

任何想法。注意

@genes = (\@lengths, \@names);

实现我想要的目标。

3 个答案:

答案 0 :(得分:5)

你至少可以这样做:

foreach my $i ( 0 .. $num-1 ) {
    push @genes, [$names[$i], $lengths[$i]];
}

如果您不关心输入数组,可以使用它们:

push @genes, [shift @names, shift @lengths] while @names;

还有一些模块可用于迭代多个列表。例如,使用List::MoreUtils::each_array

use List::MoreUtils qw( each_array );
my $it = each_array( @names, @lengths );
while (my ($n, $l) = $it->()) {
    push @genes, [$n, $l];
}

此外,List::MoreUtils::pairwise

use List::MoreUtils qw( pairwise );
@genes = pairwise{ [our $a, our $b] } @names, @lengths;

ysth建议Algorithm::Loops::MapCarE

use Algorithm::Loops 'MapCarE';
@genes = MapCarE { \@_ } \( @names, @lengths );

答案 1 :(得分:4)

你可以写

my @genes = map [ $names[$_], $lengths[$_] ], 0 .. $#names;

答案 2 :(得分:1)

顺便提一下,只需删除一些代码就可以清除原始代码 不必要的逻辑:

foreach my $i ( 0 .. $num-1 ) {
    foreach my $j ( 0 .. 1 ) {
        if ($j == 0){ push @{ $genes[$i] }, $names[$i];}
        if ($j == 1){ push @{ $genes[$i] }, $lengths[$i];}
    }
}

你循环遍历0和1,然后测试你是否在0或1,然后 执行一个动作或另一个动作?只需每次执行两个操作:

foreach my $i ( 0 .. $num-1 ) {
  push @{$genes[$i]}, $names[$i];
  push @{$genes[$i]}, $lengths[$i]
}

可能你开始想要遍历索引,然后想到你 由于内部阵列尚未存在,因此无法做到这一点,并且回归到了 这个push构造。但是,呃,在您push之前,数组不存在 他们也来到这里。循环索引很好:

my @helper = (\@names, \@lengths);
foreach my $i ( 0 .. $#names ) {
    foreach my $j ( 0 .. 1 ) {
        $genes[$i][$j] = $helper[$j][$i];
    }
}