Perl 如何将数据推送到多维数组?

Perl 如何将数据推送到多维数组?,perl,multidimensional-array,reference,Perl,Multidimensional Array,Reference,我想创建10个一维数组,将这10个一维数组放到另一个一维数组中,并将一些数据存储到数组的某个特定索引中 但是我期望的结果应该是 expect output real output 0 1 1 1 0 1 3 1 0 1 5

我想创建10个一维数组,将这10个一维数组放到另一个一维数组中,并将一些数据存储到数组的某个特定索引中

但是我期望的结果应该是

expect output         real output
    0                      1
    1                      1
    0                      1
    3                      1
    0                      1
    5                      1
    0                      1
    7                      1
    0                      1
    0                      1
这是我的密码

@Hits = ();

# Create 10 one dimension array
for($i=0;$i<=9;$i++)
{
    @Space = ();
    push(@Hits,\@Space);
}

# Store some data to some index
push(@{$Hits[1]},1);
push(@{$Hits[3]},3);
push(@{$Hits[5]},5);
push(@{$Hits[7]},7);

# print the first element of 10 arrays
for($i=0;$i<=9;$i++)
{
    print $Hits[$i]->[0];
    print "\n";
}
@Hits=();
#创建10个一维数组

对于($i=0;$i我更改代码如下:

#! /usr/bin/perl -w
@Hits = ();

push(@{$Hits[1]},1);
push(@{$Hits[3]},3);
push(@{$Hits[5]},5);
push(@{$Hits[7]},7);

#print the content of
for($i=0;$i<=9;$i++)
{
    if (defined ($Hits[$i])) {
        print "$Hits[$i][0]\n";
    } else {
        print "0\n";
    }
}
!/usr/bin/perl-w
@点击率=();
推送(@{$Hits[1]},1);
推送(@{$Hits[3]},3);
推送(@{$Hits[5]},5);
推送(@{$Hits[7]},7);
#打印

对于($i=0;$i而言,问题在于没有正确声明变量

使用严格;使用警告;
这将禁止常见的错误源,警告不确定的内容,并强制您正确声明所有变量

默认情况下,所有未声明的变量都被视为全局变量

for($i=0;$i<=9;$i++)
{
    @Space = ();
    push(@Hits,\@Space);
}
我们使用
Data::Dumper
(更容易理解):


所以我说解决方案是声明变量。具体来说,我们需要词法变量。这些变量只在声明它们的块内可见。这使得关于代码的推理更加容易。我们可以这样声明词法变量:

my $foo = 123;
当我们有一个像

my @Hits;
for my $i  (0 .. 9) {
  my @Space;
  push @Hits, \@Space;
}
然后每次执行
my
时,我们都会得到一个新的
@Space
。哦,我使用了一个foreach循环,它使用(词法)
$I
变量在
0..9
范围内迭代。我发现这比您使用的C风格循环更容易理解

由于
@Hits
中的每个元素现在都是不同的arrayref,因此我们得到了预期的数据结构。作为
data::Dump
输出:

[[], [1], [], [3], [], [5], [], [7], [], []]
当我们现在执行打印出每个子数组的第一个值的循环时,您可能会对数字之间的空行感到惊讶。这是因为例如,第一个arrayref在索引
0
处没有条目,因此返回特殊的
undf
值。当用作字符串时,这是空字符串。如果您遵照我的建议,并且
使用了警告
,您还会收到一条消息,说明您正在打印未初始化的值

我们可以通过测试定义性来解决这个问题,否则就提供一个零。由于perl5 v10,我们可以使用定义的or运算符
/
(在早期的perls中,
|
逻辑or必须这样做)

我们还可以改进其他一些方面:

  • 我们不必手动创建
    @Space
    数组;当您取消引用像
    @{$Hits[$i]}
    这样的数组条目时,Perl会在幕后执行此操作。这称为自动激活
  • 我们不仅可以遍历范围,还可以遍历数组。这比硬编码索引要好得多
  • 从v10开始,您可以使用
    say
    功能。
    say
    功能与
    print
    完全相同,但在末尾添加了一个换行符
下面是我如何编写代码的:

#!/usr/bin/perl
use strict; use warnings; use feature 'say';

my @Hits;

for my $i (1, 3, 5, 7) {
  push @{ $Hits[$i] }, $i;
}

for my $arrayref (@Hits) {
  say $arrayref->[0] // 0;
}
输出:

0
1
0
3
0
5
0
7
(请注意,我们从未在位置8和9处初始化值,因此未显示它们。我们可以通过迭代切片
@Hits[0..9]
)来修正此问题)

perl-e“use Data::Dump;@sf=();push{$sf[0]},“0”;push{$sf[1]},“1”;dd\@sf;”
[[0], [1]]

perl-e“使用数据::转储;@sf=();push@sf,[“0”];push@sf,[“1”];dd\@sf
[[0], [1]]
for my $i (0 .. 9) {
  my $value = $Hits[$i][0] // 0;
  print "$value\n";
}
#!/usr/bin/perl
use strict; use warnings; use feature 'say';

my @Hits;

for my $i (1, 3, 5, 7) {
  push @{ $Hits[$i] }, $i;
}

for my $arrayref (@Hits) {
  say $arrayref->[0] // 0;
}
0
1
0
3
0
5
0
7