2010-11-13 4 views
2

Comment générer un hachage de hachage à partir d'une série de tableaux? Je dois aller de ceci:Enregistrement de la base de données dans Hash-of-hashes

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

à ceci:

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

Il est utilisé pour transformer la sortie d'une requête de base de données à une structure hiérarchique pour la visualisation. Par conséquent, la longueur de @data est fixée pour tous les enregistrements, mais varie d'une requête à l'autre.

Répondre

7

En supposant que vous voulez dire pour initialiser @data avec les éléments de l'un », « deux » et « trois » ci-dessus, vous pouvez faire quelque chose comme ceci:

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

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

Ce que cela fait est d'initialiser une variable la valeur imbriquée finale, puis à plusieurs reprises construire un hachage pointant vers le contenu de cette variable, en utilisant une touche sortie de la fin du tableau de données.

0

Pas tout à fait comme perlienne ou compact de swestrup mais peut-être plus facile à suivre:

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

utilisation List::Util est de réduire la fonction de construire le hashref en arrière, créant une hashref qui devient la valeur de la hashref supérieure, à partir avec le $value qui reste une valeur, pas une clé. Cela évite la nécessité d'opérations destructrices comme pop:

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

Vous devrez peut-être supprimer les 'Name "main::b" used only once: possible typo at ' avertissements en enfermant le code dans un bloc et en éteignant l'avertissement 'once' temporairement dans ce bloc avec

no warnings 'once'; 

comme ceci:

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

Enfin, un I ** aime **! – tchrist

Questions connexes