为了帮助我学习Perl,我构建了以下数据结构,其中内部哈希(/ DriveA / archive等)是哈希引用:
#The contents of the %properties hash of hashes
#The inner hash is a hash reference to a hash named %attributes
$VAR1 = {
'/DriveA' => {
'/DriveA/archive/' => {
'MaxSize' => '20GB',
'Size' => '19GB',
'Free' => '5'
},
'/DriveA/current/' => {
'MaxSize' => '20GB',
'Size' => '12GB',
'Free' => '40'
}
},
'/DriveB' => {
'/DriveB/archive/' => {
'MaxSize' => '8GB',
'Size' => '6GB',
'Free' => '25'
},
'/DriveB/current/' => {
'MaxSize' => '80GB',
'Size' => '20GB',
'Free' => '75'
}
},
'/DriveC' => {
'/DriveC/' => {
'MaxSize' => '20GB',
'Size' => '10GB',
'Free' => '50'
}
}
}
我使用以下方法创建了一个数组来保存%attributes
的键(也就是%属性中的值/哈希引用):
@list = sort keys %attributes;
我正在尝试迭代@list
中的元素,并在%properties
中找到外部哈希的关联键。因此,例如,如果/DriveA/archive/
是数组中的下一个项目,我想从/DriveA
中找到与该值%properties
相关联的哈希键,假设取消引用内部哈希
我创建了一个反向哈希,它输出以下内容......
$VAR1 = {
'HASH(0x2002f244)' => '/DriveB',
'HASH(0x2002f388)' => '/DriveC',
'HASH(0x2002f1e4)' => '/DriveA'
}
...使用此代码...
foreach my $item (@list) {
my %rhash = reverse %properties; # Reverse the hash of hashes so value is key
print Dumper(\%rhash);
}
鉴于上述情况,我将如何取消引用哈希,以便在哈希引用中找到$item
,以便我可以确定关联值(而不是哈希引用值)。
如果$item = '/DriveA/archive/'
,我想在'/DriveA'
的变量中捕获%properties
,以便可以从子例程返回。
我知道内部哈希需要被解除引用,我只是不确定如何去做。我通读了perlref,perldsc和perllol,但我找不到答案。
感谢。
答案 0 :(得分:1)
最简单的方法是直接通过遍历数据结构生成反向键:
my %reverse_keys;
foreach my $outer_key (keys %properties) {
my $inner_hashref = $properties->{$outer_key};
my %reverse_map = map { ($_ => $outer_key) } keys %$inner_hashref;
%reverse_keys = (%reverse_keys, %reverse_map);
}
理想情况下,您甚至可以在将数据存储到%属性的同时直接生成%reverse_keys
,因此您不需要上面的额外遍历代码。
解决您的实际技术问题:
您开始使用哈希引用(基本上是C语言中的指针)。
然后将该哈希引用作为键分配给哈希。
将某些内容指定为散列键会将其置于字符串上下文(标量上下文的特例)。
当您在Perl中对字符串进行字符串化时,它会变成该引用的字符串表示形式 - 这是您在Data :: Dumper反向散列时看到的HASH(0x2002f244)
字符串。
在技术层面上,您要问的是“如何将哈希引用的字符串表示形式转换回哈希引用本身?”
Perl FAQ 4中介绍了这一点。据我所知,你不能轻易地将哈希引用的字符串表示形式转换回哈希引用本身。
如果您绝对必须(我强烈建议您反对 - 请使用答案顶部的解决方案) - 您可以使用Devel::Pointer
CPAN模块执行此操作。
使用该模块的解决方案显示在this PerlMonks thread。
另一种解决方案可能是使用Tie::RefHash
模块来使用实际的哈希引用而不是它们的字符串表示作为键。这将在第8.5.1章中介绍。 O'Reilly的“Programming Perl,3rd edition”中的“引用不作为哈希键”。我也建议不要那么疯狂。