2010-11-13 86 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