2015-07-22 44 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;' –