从Perl中的列表创建数组数组

时间:2014-03-10 03:17:10

标签: arrays perl data-structures

我想从对象列表中创建一个数组数组。但是如何重置数组变量(@row并重用它来保存下一节中的项目)?我知道@row被声明一次,当它被推入数组时,清空它也会清空@arrays。如何在不清空@arrays的情况下重置@row?

 use Data::Dumper;

    # sample data, could be a long list for complex data types
    my @list = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);

    my @arrays;
    my @row;
    my $numSub = 10;

    foreach my $itm (@$list)  {
       if (scalar(@row) == $numSub) 
       {   
          push @arrays, \@row;
          @row = (); # clear array, cleared the array of arrays
          push @row, $itm;
        }
        else {
          push @row, $itm;
       }
   }
   # push the last reminder
    push @arrays, \@row;

   Dumper @arrays; # nothing 

3 个答案:

答案 0 :(得分:1)

创建一个新的匿名数组而不是仅仅引用一个引用,或者@arrays的所有元素都将指向相同的数组引用。

push @arrays, [@row];

另外,如果您的目标只是构建10个或更少的组,那么您可以使用以下方法:

while (@list) {
    push @array, [splice @list, 0, 10];
}

答案 1 :(得分:1)

my @row放在foreach循环内而不是外面。然后每次循环都会有一个不同的变量。

顺便提一下,有更好的方法来写这个,例如:

my @copy = @list;
while (@copy) {
  push @arrays, [ splice @copy, 0, $numSub ];
}

use List::Util 'max';
for (my $i = 0 ; $i < @list ; $i += $numSub) {
  push @arrays, [ @list[ $i .. max($i + $numSub, $#list) ] ];
}

use List::MoreUtils 'natatime';
my $iter = natatime $numSub, @list;
while (my @vals = $iter->()) {
  push @arrays, \@vals;
}

答案 2 :(得分:0)

您的代码存在一些问题,因为它可以防止它首先工作。

  • 您必须在每个Perl程序的开头始终 use strictuse warnings。这会提醒您第二个问题

  • 您正在循环@$list,如果$list是数组引用,那就没问题了,但您定义的数据在@list中,您需要使用它

  • Dumper函数只是返回格式化的字符串。目前你只是丢弃它。要查看它,您需要使用print Dumper \@arrays

  • 目前,@arrays包含对相同数组的多个引用。每次将新的临时数组添加到列表中时,您必须复制 @row。最简单的方法是push @arrays, [ @row ]

该程序可以满足您的需求。

use strict;
use warnings;

use Data::Dumper;

my @list = 1 .. 20;

my @arrays;
my @row;
my $numSub = 10;

for my $itm (@list) {
  if (@row == $numSub) {
    push @arrays, [@row];
    @row = ();
  }
  push @row, $itm;
}

push @arrays, [@row];

print Dumper \@arrays;

<强>输出

$VAR1 = [
          [
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9,
            10
          ],
          [
            11,
            12,
            13,
            14,
            15,
            16,
            17,
            18,
            19
          ]
        ];