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

标签 perl multidimensional-array reference

我想创建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";
}

谢谢

最佳答案

问题是您没有正确声明变量。对于每个脚本,您应该

use strict; use warnings;

这将禁止常见的错误来源,警告不确定的东西,并强制您正确声明所有变量。

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

for($i=0;$i<=9;$i++)
{
    @Space = ();
    push(@Hits,\@Space);
}

@Space 在每次迭代中引用同一个数组。因此,@Hits 中的所有十个条目都是对同一数组的引用。让我们看看 @Hits 实际上是什么。我们可以使用 Data::DumperData::Dump 模块(后者通常产生更漂亮的输出):

use Data::Dump;  # use Data::Dumper;
dd \@Hits;       # print Dumper \@Hits;

我们得到 Data::Dumper(更容易理解):

$VAR1 = [
          [
            1,
            3,
            5,
            7
          ],
          $VAR1->[0],
          $VAR1->[0],
          $VAR1->[0],
          $VAR1->[0],
          $VAR1->[0],
          $VAR1->[0],
          $VAR1->[0],
          $VAR1->[0],
          $VAR1->[0]
        ];

所以我说解决方案是声明你的变量。具体来说,我们需要词法变量。这些变量仅在声明它们的 block 内部可见。这使得对代码的推理变得更加容易。我们可以像这样声明一个词法变量:

my $foo = 123;

当我们有一个像这样的循环时

my @Hits;
for my $i  (0 .. 9) {
  my @Space;
  push @Hits, \@Space;
}

然后每次执行 my 时,我们都会得到一个 new @Space。哦,我使用了一个 foreach 循环,它使用(词法)$i 变量迭代范围 0 .. 9。我发现这比您使用的 C 样式循环更容易理解。

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

[[], [1], [], [3], [], [5], [], [7], [], []]

当我们现在执行打印出每个子数组的第一个值的循环时,您可能会对数字之间的空行感到惊讶。这是因为例如第一个 arrayref 在索引 0 处没有条目,因此返回特殊的 undef 值。当用作字符串时,这是空字符串。如果您听从了我的建议并执行了use warnings,您还会收到一条消息,表明您正在打印一个未初始化的值。

我们可以通过测试定义性来解决这个问题,否则提供零。从 perl5 v10 开始,我们可以为此使用定义或运算符 //(在早期的 perls 中,|| 是逻辑或必须做的)。

for my $i (0 .. 9) {
  my $value = $Hits[$i][0] // 0;
  print "$value\n";
}

还有一些我们可以改进的地方:

  • 我们不必手动创建 @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 初始化值,因此它们没有显示出来。我们可以通过迭代 slice @Hits[0 .. 9]。)

关于perl - 如何将数据推送到多维数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17895308/

相关文章:

java - 无法将 int[] 类型添加到 ArrayList

c - C中有像堆栈一样快的指针吗? (没有间接但仍然是堆)

linux - 如何将/etc/passwd 存储在散列或数组中?

Perlcritic 认为哈希是用逗号分隔的语句

regex - 如何从 Perl 中的字符串中提取单个字符或封闭的分组?

mysql - 使用 Perl 更新 Ruby on Rails "created_at"日期

javascript - 用多维数组制作下拉菜单

c - 关于从二维动态数组中检索值

ruby-on-rails - Ruby - 添加到多维数组

delphi - 如何确定所有单元的依赖关系? (估计重构成本)