现在我正在修改代码 我正在使用代码创建哈希haivng重复键。它给出了语法错误。
use strict;
use warnings;
my $s = "12 A P1
23 B P5
24 C P2
15 D P1
06 E P5";
my $hash;
my @a = split(/\n/, $s);
foreach (@a)
{
my $c = (split)[2];
my $d = (split)[1];
my $e = (split)[0];
push(@{$hash->{$c}}, $d);
}
print Dumper($hash );
我的输出为
$VAR1 = {
'P5' => [
'B',
'E'
],
'P2' => [
'C'
],
'P1' => [
'A',
'D'
]
};
但我希望输出像
$VAR1 = {
'P5' => {
'E' => '06',
'B' => '23'
},
'P2' => {
'C' => '24'
},
'P1' => {
'A' => '12',
'D' => '15'
}
};
如何做到
答案 0 :(得分:4)
您的哈希声明不正确,应该是:
my %hash = ();
或简单地说:
my %hash;
然后你的其余代码太复杂而且不正确。
foreach (@a) {
my ($k, $v) = (split);
push @{$hash{$k}}, $v;
}
应该足够了。请参阅Autovivification了解其原因。
使用您的代码,第一次看到密钥时,您将$hash{$k}
设置为标量。然后你不能push
那个键的东西 - 它必须是一个数组开始。
if (-e $hash{$c})
测试错误。 -e
是文件存在测试。如果您想知道是否存在哈希键,请使用:
if (exists $hash{$c}) { ... }
而print %hash;
将无法满足您的期望(print %{$hash};
无效)。如果您这样做,您将获得更漂亮的显示:
use Data::Dumper;
print Dumper(\%hash);
(很好的调试,这个Data::Dumper
。)
答案 1 :(得分:2)
{p} %hash
是散列,$hash
是标量(散列引用,如\%hash
),它们是两个不同的变量
要引用$hash
,要引用其引用存储在标量变量$hash
中的哈希值,您必须使用$hash->{$c}
或{{1} }
更新:
$$hash{$c}
答案 2 :(得分:2)
Perl告诉你究竟出了什么问题。您已使用strict
编译指示,因此使用%hash
变量而不声明它是语法错误。虽然字符串%hash
未出现在您的代码中,但字符串$hash{...}
会在每个问题行中出现。这是访问%hash
元素的语法,这就是严格抱怨的原因。
您已声明变量$hash
,因此访问包含的哈希引用的元素将写为$$hash{...}
或$hash->{...}
。修复问题行以访问正确的变量,代码将编译。
答案 3 :(得分:1)
查看工作代码,修复错误(代码中的注释)以及结果输出:
use strict;
use warnings;
my $s = "P1 26
P5 23
P2 24
P1 15
P5 06 ";
my %hash; #my $hash ={};
#my $arr = [];
my @a = split(/\n/, $s);
foreach (@a)
{
my $d = (split)[1];
my $c = (split)[0];
push(@{$hash{$c}}, $d); #if ...
}
while (my ($key, $value) = each(%hash)) #print %{$hash};
{
print "$key @{$value}\n";
}
#Output:
#P5 23 06
#P2 24
#P1 26 15
答案 4 :(得分:0)
(奇怪。到目前为止发布的所有答案中,没有人真正回答过这个问题......)
以下代码生成要求的结果。原始代码中似乎缺少的基本位是两级哈希。
顺便说一下,似乎没有理由将外部哈希作为hashref而不是哈希,所以我把它作为哈希。您还可以在一行中选择拆分为变量。
use strict;
use warnings;
use Data::Dumper;
my $s = "12 A P1
23 B P5
24 C P2
15 D P1
06 E P5";
my %hash;
my @a = split(/\n/, $s);
foreach (@a)
{
my ($e, $d, $c) = (split);
$hash{$c}{$d} = $e;
}
print Dumper(\%hash);