2010-11-13 64 views
2

如何从一系列数组中生成哈希散列哈希?我需要这样走:数据库记录散列哈希

my @data = /one two three/; 
my $value = 13: 

这样:

$hoh = { 'one' => { 'two' => { 'three' => 13 } } }; 

这是用于数据库查询的输出转换为一个层次结构的可视化。因此@data的长度对于所有记录是固定的,但是在查询之间不同。

回答

7

假设你的意思是初始化@data随份子“一”,“二”和“三化”上面,那么你可以做这样的事情:

my @data = qw/one two three/; 
my $value = 13;

my $hash = $value; $hash = {pop @data => $hash} while @data;

这样做什么是一个变量初始化成最后的嵌套值,然后使用从数据数组末尾弹出的键重复构建指向该变量内容的散列。

0

没有这么Perlish的或紧凑swestrup的,但也许更容易理解:

my @data = qw/one two three/; 
my $value = 13; 
my %h  = (); # This is your final hash 

my $deepest = undef; 
my $hr  = \%h; 
for my $x (@data) { 
     $hr->{$x} = { }; 
     $deepest = \$hr->{$x}; 
     $hr  = $hr->{$x}; 
} 
$$deepest = $value; 
5

使用List::Util的减少功能向后构建hashref,打造成为上hashref的价值hashref,开始与$value这仍然是一个价值,而不是一个关键。这样就避免了像pop需要进行破坏性操作:

my $d = reduce { +{ $b => $a } } ($value, reverse @data); 

您可能需要封闭的代码块,并暂时关闭'once'警告在该块压制'Name "main::b" used only once: possible typo at '警告

no warnings 'once'; 

像这样:

use strict; 
use warnings; 
use List::Util 'reduce'; 
my @data = qw{one two three}; 
my $value = 13; 

my $d = do { 
    no warnings 'once'; 
    reduce { +{ $b => $a } } ($value, reverse @data); 
}; 
+0

最后,一个我**喜欢**! – tchrist 2010-11-14 02:39:35