如何在Perl中创建哈希的哈希?

8

根据我对Perl中哈希的当前理解,我预计这段代码会打印“hello world”。但实际上它什么也没有输出。

%a=();

%b=();
$b{str} = "hello";  
$a{1}=%b;

$b=();
$b{str} = "world";
$a{2}=%b;

print "$a{1}{str}  $a{2}{str}"; 

我假设哈希就像数组一样,那么为什么我不能让一个哈希包含另一个哈希呢?

3
为什么这不起作用的简短而精要的原因是,基本上哈希表或数组只能包含标量值,而哈希表本身不是标量值。但是,哈希引用是标量值。 :) 下面的答案有一些关于为什么如此的好链接。 - Robert P
6个回答

6
  1. 你应该在程序中始终使用"use strict;"。

  2. 使用引用和匿名哈希。

use strict;use warnings;
my %a;

my %b;
$b{str} = "hello";  
$a{1}={%b};

%b=();
$b{str} = "world";
$a{2}={%b};

print "$a{1}{str}  $a{2}{str}";

{%b} 创建对哈希表 %b 副本的引用。你需要创建副本是因为你之后会清空它。


1
@Mike:使用严格模式应该是标准,而不是特例。 - Ether
@ether 我现在意识到了,我正在学习Perl,刚刚发现了strict - Mike

6

哈希的哈希在第一次时很难做到正确。在这种情况下

$a{1} = { %b };
...
$a{2} = { %b };

让你去想去的地方。

参见perldoc perllol,了解有关Perl中二维数据结构的详细信息。


1
perldoc perllol 全是关于数组的,我想。perldoc perldsc 涉及到更复杂的情况(包括哈希)。我还强烈推荐 perldoc perlreftut 给那些刚接触 Perl 引用的人。 - Telemachus

4

简短回答:哈希键只能与标量关联,而不能与哈希关联。如果要实现您想要的功能,需要使用引用。

与其重新解释如何创建多级数据结构,我建议您阅读perlreftut。perlref更完整,但一开始会有点压抑。


谢谢!我忘记了perldsc。我不得不查看perlref才想起perlreftut的存在。 :-) 我认为我应该重新熟悉一下文档。 - David Wall
@davidwall 浏览文档总是很好的,但特别要注意的是教程部分,这个容易被忽略但不容错过。我特别记得喜欢 perlreperlreftutperldscperlopentutperltoot(也许这个已经过时或者与 Perl 中当前最佳实践脱节了 - 不确定)和 perlstyle - Telemachus

2

Mike,Alexandr的回答是正确的。

此外,还有一个提示。如果你正在学习哈希表,Perl语言有一个名为Data::Dumper的模块,可以为你漂亮地打印数据结构,这在你想要检查数据结构的值时非常方便。

use Data::Dumper;
print Dumper(\%a); 

当您打印此内容时,它会显示出来。

$VAR1 = {
          '1' => {
                   'str' => 'hello'
                 },
          '2' => {
                   'str' => 'world'
                 }
        };

1

Perl 喜欢扁平化你的数据结构。这通常是一件好事...例如,(@options, "another option", "yet another") 最终会变成一个列表。

如果你真的想要一个结构体内嵌另一个结构体,那么内部结构体需要是一个引用。就像这样:

%a{1} = { %b };  

花括号表示哈希表,你正在从%b中填充值,并以引用而不是直接哈希表的形式返回。

你也可以这样说

$a{1} = \%b;   

但这会同时更改 %b 和 $a{1}。


0
我需要创建1000个员工记录来测试T&A系统。员工记录存储在哈希表中,其中键是员工的身份证号码,值是其姓名、出生日期和入职日期等信息的哈希表。以下是具体步骤...
# declare an empty hash
%employees = ();

# add each employee to the hash
$employees{$identity} = {gender=>$gender, forename=>$forename, surname=>$surname, dob=>$dob, doh=>$doh};

# dump the hash as CSV
foreach $identity ( keys %employees ){
    print "$identity,$employees{$identity}{forename},$employees{$identity}{surname}\n";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接