如何使用重复键创建哈希

时间:2011-12-23 07:42:07

标签: arrays perl hash

现在我正在修改代码 我正在使用代码创建哈希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'
      }
     };

如何做到

5 个答案:

答案 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} }

请参阅References quick reference

更新:

$$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);