在Perl中使用for循环遍历多维数组的一个维度

时间:2014-06-30 19:10:23

标签: arrays perl loops multidimensional-array

错误的

*更新*

另一个PERL问题....我试图循环一个2D数组。我对一个维度的大小持肯定态度,但对第二维度不确定。代码段:

foreach my $value (@surfaces[1])
                {
                    my $sum = 0;
                    my $smallest = 9999;
                    my $limit_surface = 0;
                    for (my $i = 0; $i < 3; $i++)
                    {
                        $sum += $surfaces[$i][$counter];
                        if ($surfaces[$i][$counter] <= $smallest)
                        {
                            $smallest = $surfaces[$i][$counter];
                            $limit_surface = $subchannel_number[$i];
                        }
                    }
                    $counter++;
                    push(@avg_value,$sum/@rodsurface_number);
                    push(@limiting_schan,$limit_surface);
                    push(@limiting_value,$smallest);
               }

我已编译但$ value变量未能初始化。

3 个答案:

答案 0 :(得分:4)

在我之后重复:

Perl没有多维数组
Perl没有多维数组
Perl没有多维数组

Perl所拥有的是 arrays ,其中包含指向其他数组的引用。您可以在Perl中模拟多维数组,但它们不是真正的多维数组。例如:

my @array;
$array[0] = [ 1, 2, 3, 4, 5 ];
$array[1] = [ 1, 2, 3 ];
$array[2] = [ 1, 2 ];

我可以谈论$array[0][1]$array[2][1],但$array[0][3]存在,$array[2][3]不存在。

如果您不理解参考文献,请阅读tutorial on references

你需要做的就是浏览你的数组,然后找出每个子数组的大小并浏览每个子数组。

无法保证
  1. 主数组中包含的引用实际上指向另一个数组:
  2. 您的子数组仅包含标量数据。
  3. 您可以使用$#运算符查找数组的大小。例如,$#array是数组中的项目数。您可以使用( 0..$#array )遍历数组中的每个项目,这样就可以使用索引。

    use strict;
    use warnings;
    
    my @array;
    $array[0] = [ 1, 2, 3, 4, 5 ];
    $array[1] = [ 1, 2, 3 ];
    $array[2] = [ 1, 2, ];
    
    #
    # Here's my loop for the primary array.
    #
    for my $row ( 0..$#array ) {
        printf "Row %3d: ", $row ;
        #
        # My assumption is that this is another array that contains nothing
        # but scalar data...
        #
        my @columns = @{ $array[$row] };  # Dereferencing my array reference
        for my $column ( @columns ) {
            printf "%3d ", $column;
        }
        print "\n";
    }
    

    注意我已my @columns = @{ $array[$row] };引用转换回数组。这是一个额外的步骤。我可以在我的for循环中完成解除引用并保存一个步骤。

    打印出来:

    Row   0:   1   2   3   4   5 
    Row   1:   1   2   3 
    Row   2:   1   2 
    

    我可以在这里进行一些安全检查。例如,我可能想要验证每一行的大小,如果一行与另一行不匹配,请抱怨:

    my $row_size = $array[0];
    for my $row ( 1..$#array ) {
        my @columns = @{ $array[$row] };
        if ( $#columns ne $array_size ) {
            die qq(This is not a 2D array. Not all rows are equal);
        }
    }
    

答案 1 :(得分:2)

您没有描述您的数据结构,也没有准确解释您想要用它做什么。这限制了我们可以给予一般变化的建议。

如果你试图遍历一个数组数组,我会建议你根据元素而不是索引来做。

例如,下面我有一个4乘5的整数矩阵。我想找到这些值的平均值。一种方法是简单地迭代每一行然后列,并将值相加:

use strict;
use warnings;

my @AoA = (
    [11, 12, 13, 14, 15],
    [21, 22, 23, 24, 25],
    [31, 32, 33, 34, 35],
    [41, 42, 43, 44, 45],
);

my $sum = 0;
my $count = 0;

for my $row (@AoA) {
    for my $element (@$row) {    # <-- dereference the array ref
        $sum += $element;
        $count++;
    }
}

print "Average of Matrix is " . ($sum / $count) . "\n";

输出:

Average of Matrix is 28

有关复杂数据结构的更多信息,请查看:Perl Data Structures Cookbook

答案 2 :(得分:1)

我已经设置了一些虚拟变量并改变了一些东西。这将编译并生成我在下面显示的结果。

这可能无法解答您的问题,但应该允许您复制并粘贴代码,自行运行代码,编辑输入并查看输出与您想要的内容的对比情况。

use warnings;
use strict;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;

my @surfaces = ( ['1','2','3'],
            ['10','20','30'],
            ['100','200','400'],
            );

my @subchannel_number = ( ['1','2','3'],
            ['10','20','30'],
            ['100','200','400'],
            );  

my @rodsurface_number = (1 .. 10);
my $counter = 0;

my (@avg_value, @limiting_schan, @limiting_value);

foreach my $value ($surfaces[1]){
    my $sum = 0;
    my $smallest = 9999;
    my $limit_surface = 0;
        for (my $i = 0; $i < 3; $i++) {
            $sum += $surfaces[$i][$counter];
                if ($surfaces[$i][$counter] <= $smallest){
                    $smallest = $surfaces[$i][$counter];
                    $limit_surface = $subchannel_number[$i];
                }
        }
        $counter++;
        push(@avg_value,$sum/@rodsurface_number);
        push(@limiting_schan,$limit_surface);
        push(@limiting_value,$smallest);
}

print Dumper (\@avg_value, \@limiting_schan, \@limiting_value);

$VAR1 = [
          '11.1'
        ];
$VAR2 = [
          [
            '1',
            '2',
            '3'
          ]
        ];
$VAR3 = [
          1
        ];