【问题标题】:Perl Hash of Arrays of Arrays数组数组的 Perl 哈希
【发布时间】:2011-07-02 06:47:43
【问题描述】:

我的多维数组哈希中的一些变量会在我离开 for 循环后立即消失。变量在循环中一个接一个地正确打印,但是当我在循环外打印任何项目时,除了第一项之外,它始终为空。

for my $y (0..$last_row - 2) {
    my $mlid = $Sheet->Cells($y+2, 1)->{'Value'}; 
    my @a = ();
    $a[0] = $Sheet->Cells($y+2, 3)->{'Value'}; 
    $a[1] = $Sheet->Cells($y+2, 4)->{'Value'}; 
    $a[2] = $Sheet->Cells($y+2, 6)->{'Value'}; 
    $a[3] = $Sheet->Cells($y+2, 7)->{'Value'}; 
    $a[4] = $Sheet->Cells($y+2, 8)->{'Value'}; 
    push @{$longHash{$mlid}}, [ @a ];
    print "Item in Array in Hash: $longHash{$mlid}[1][0]\n"; #this prints nothing

    if (exists $numPeople{$mlid}){
        $numPeople{$mlid}++;
    }else{
        $numPeople{$mlid} = 0;
        $numPeople{$mlid}++;
    }
}

print "Item in Array in Hash: $longHash{7202}[0][0]\n"; #this prints properly
print "Item in Array in Hash: $longHash{7202}[1][0]\n"; #this prints nothing

行为应该是:

我有一个哈希。单个 mlid 的键给出了一个数组(代表一个人)。 在每个数组中,应该有另一个数组,其中 0-4 索引是从我正在读取的 Excel 文件中定义的。

所以,要从 mlid 7202、第 7 个人和 Excel 中的第 4 列获取数据,我应该输入 $longHash{7202}[7][1](因为我将第 4 列映射到第 1 列数组的值。)

【问题讨论】:

  • 您刚刚更改了代码,现在$y 不是哈希的索引。您能否发表评论并说出行为应该是什么?我认为您现在需要做的就是将$longHash{7202}[0][0] 更改为$longHash{7202}[0]
  • 如果您正在使用 $longHash{7202}[0] 而不是 $longHash{7202}[0][0],请将 push @{$longHash{$mlid}}, [ @a ]; 更改为 $longHash{$mlid} = [ @a ];
  • 但我需要 3 层的额外信息。 MLID、人员、人员统计信息。每个都有多个,我无法摆脱一层。
  • 好的,正在检查。我已经更新了我的答案。我认为您的代码现在应该可以工作了。如果不是,请尝试我的示例,看看它是否有效。如果是这样,那么可能存在不同的问题。例如,$mlid==7202 中可能只有一个人。尝试添加use strict; use warnings;

标签: arrays perl hash multidimensional-array perl-data-structures


【解决方案1】:

您在循环的每次迭代中都覆盖了$longHash{$mlid},因此在最好的情况下,$longHash{7202}[$x] 只会为$x 的一个值定义。

除非你做的事情比你在这里展示的要复杂得多,否则我认为你根本不需要清除 $longHash{$mlid}。说

$longHash{key}[index] = expression

将自动激活$longHash{key}$longhash{key}[index],无需任何预初始化。

($longHash{$mlid} = () 也看起来有点奇怪——你将一个空列表分配给一个标量变量。我认为这与说 $longHash{$mlid}=0 没有什么不同。如果你打算将它设置为一个空数组引用,那么您应该使用[] 而不是())。

【讨论】:

  • 我注意到覆盖并对其进行了编辑。主要问题似乎是找到该语句中的索引。我更改了代码以进行推送调用,但这也不起作用。我只希望索引是我要添加到的当前数组的确切大小。
【解决方案2】:

我发现了两个问题。

  1. $longHash{$mlid} = ()

您正在尝试将标量字段设置为列表。 {$mlid}` 应该设置为列表 ref,而不是列表。最简单的解决方法是 $longHash{$mlid} = [],但这并不能解决真正的问题。

2。 $longHash{$mlid}[$y] = [ @a ]; 结合$longHash{$mlid} = ();

您在每次通过循环时清除$longHash{$mlid},然后尝试分配给非零索引。也许你在这里想要的是散列的散列而不是列表的散列。

更新

我认为在你的新版本中

push @{$longHash{$mlid}}, [ @a ];

应该是

$longHash{$mlid} = [ @a ];

更新 2

我认为您的代码现在应该可以工作了。

这似乎相当于我下面的简化示例:

my %hash;

my @a;
$a[0] = "Fred";
$a[1] = 31;
$a[2] = "Melbourne";

push @{$hash{7202}}, [ @a ];

$a[0] = "Mary";
$a[1] = 25;
$a[2] = "Sydney";

push @{$hash{7202}}, [ @a ];

print $hash{7202}[0][0] . "\n";
print $hash{7202}[1][0] . "\n";

更新 3

请补充

use warnings;
use strict;

确保您认为存在的所有数组索引确实存在。

并尝试遍历您的数据以打印它,例如

for my $mlid (keys %hash) {
    my $recordref = $hash{$mlid};
    my @record = @$recordref;
    for my $i (0..scalar(@record)-1) {
        printf "mlid %s person %d name %s\n", $mlid, $i, $record[$i][0];
    }
}

【讨论】:

  • 我完全删除了 "$longHash{$mlid} = ()" 行,它仍然不打印第二个数组 "$longHash{$mlid}[1]"
  • 不,我需要一个多维数组。一个 mlid 映射到多个人(每个人都有一个数组,因为每个人都有多个值)。
猜你喜欢
  • 1970-01-01
  • 2017-02-24
  • 2014-05-12
  • 1970-01-01
  • 2011-07-26
  • 2020-07-19
  • 2012-06-12
  • 2012-07-22
  • 1970-01-01
相关资源
最近更新 更多