2015-07-22 69 views
1

我想從@array創建一個多維%hash從數組中創建散列的多維密鑰?

假設@array就像

my @array=(1,2,3,4,5); 

我想分配@array最後的值作爲最終值多維%hash

%hash=(
     1=>{ 
       2=> 
       { 
        3=> 
         { 
         4=>5 
         } 
        } 
       } 
      ) 

這意味着$hash{1}{2}{3}{4}=5;

我想要做的東西如:

for my $i (0..$#array){ 
    #push $i as key until second last element and assign last element as value 
} 

注意:@array可能是任何大小,只是我想分配@array的最後一個元素作爲值到%hash中最後一個元素之前的元素的鍵。

回答

5

首先,使用pop來分隔要從鍵分配的值。具有$p參考的下一個值來間接引用和/或修改

use Data::Diver qw(DiveVal); 

my %hash; 
DiveVal(\%hash, map \$_, @keys) = $val; 

sub dive_val :lvalue { 
    my $p = \shift; 
    $p = \($$p->{$_}) for @_; 
    $$p 
} 

my %hash; 
dive_val(\%hash, @keys) = $val; 

dive_val作品:那麼,您可以使用以下的。

Pre-loop:   $p references $hash (the anon scalar referencing %hash) 
After loop pass 0: $p references $hash->{1} 
After loop pass 1: $p references $hash->{1}{2} 
After loop pass 2: $p references $hash->{1}{2}{3} 
After loop pass 3: $p references $hash->{1}{2}{3}{4} 

間接的額外級別有很多好處。

  • 它消除了專門處理最後一個鍵的需要。
  • 它不需要在取消引用之前創建哈希。
  • 它不需要根作爲散列的引用。相反,任何標量都可以成爲根,甚至是一個未定義的標量。
  • 它可以很容易地擴展dive_val以支持混合陣列/散列結構。
+1

對不起@';'沒有這一行'$ p = \($$ p - > {$ _})。 '$$ p'是hashref,'$$ p - > $ _'是value,之後我沒有得到'\()'? –

+0

'$$ p'可以是hashref,但不一定。在循環中,它可以是undef或者哈希引用。在循環結束時,它可以是任何東西。 '\'得到一個參考。 parens只是在那裏覆蓋優先權。 – ikegami

+0

以及爲什麼你在這裏參考hash的參考'my $ p = \ shift;' –