2009-10-29 12 views
0

Je vais essayer d'illustrer ceci avec un exemple. Prenons un exemple commun d'un hachage de hachages:Comment créer et ajouter des hachages anonymes à un hachage connu pendant l'exécution du script?

my %HoH = (
    flintstones => { 
     lead => "fred", 
     pal => "barney", 
    }, 
    jetsons => { 
     lead  => "george", 
     wife  => "jane", 
     "his boy" => "elroy", 
    }, 
    simpsons => { 
     lead => "homer", 
     wife => "marge", 
     kid => "bart", 
    }, 
); 

Pour mes fins, je voudrais être en mesure d'ajouter un hash sans nom, ou anonymes% HOH. Je n'aurai pas besoin (ou pouvoir) de définir ces sous-hachages avant l'exécution. Comment puis-je accomplir cela avec Perl? Tout ce que j'ai lu (et j'ai déjà lu via Perldocs et Google) semble montrer des exemples où tous les sous-hachages (par exemple "flintstones", "jetsons" et "simpsons") sont définis.

Ce que je suis en train de faire est d'essayer de construire une table de hachage parent qui contiendra des sous-hash avec les lignes d'un fichier CSV:

%TopHash = (
    %Line1 => { 
     cell01 => $some_value1a; 
     cell02 => $some_value2a; 
     cell03 => $some_value3a; 
    }, 
    %Line2 => { 
     cell01 => $some_value1b; 
     cell02 => $some_value2b; 
     cell03 => $some_value3b; 
    }, 
    %Line3 => { 
     cell01 => $some_value1c; 
     cell02 => $some_value2c; 
     cell03 => $some_value3c; 
    }, 
# etc 
# etc 
# etc 

    ); 

Le nombre de « % LineX » hash que j'ai besoin ne sait pas jusqu'à l'exécution (car ils représentent le nombre de lignes dans un fichier CSV lu lors de l'exécution).

Des idées? Si ce n'est pas déjà clair ... j'essaie toujours d'envelopper ma tête autour des hachages Perl.

+2

BTW, êtes-vous sûr que vous voulez utiliser un HoH pour cette structure? Puisque vous êtes en train d'analyser les fichiers CSV, il semble que le hachage des tableaux soit plus approprié. En général, si vous vous trouvez en train de coller des numéros séquentiels à la fin d'une clé de hachage ou d'un nom de variable, vous devriez probablement utiliser un tableau. – friedo

+0

Mon objectif final est d'obtenir une liste de lignes avec des données uniques (comme déterminé par une combinaison de 3 cellules dans une rangée); Cependant, j'ai besoin de toutes les cellules des rangées uniques. Peut-être qu'un tableau de hachages serait mieux adapté à cette tâche? – Mick

+0

Vous avez déjà beaucoup de réponses, mais je n'ai vu personne vous pointer vers le livre de recettes Data Structures (perldoc perldsc) http://perldoc.perl.org/perldsc.html Il contient beaucoup d'exemples pour travailler avec structures de données complexes. Bien sûr, vous l'avez peut-être déjà vu depuis que vous avez lu un peu de perldoc. – daotoad

Répondre

1

D'abord, vous créez le hachage de la ligne actuelle vous l'analyse syntaxique

my %lineHash = (
    cell01 => $some_value1a, 
    cell02 => $some_value1b, 
    cell03 => $some_value1c 
); 

ou créer une référence à un hachage pur et simple

my $lineHashRef = { 
    cell01 => $some_value2a, 
    cell02 => $some_value2b, 
    cell03 => $some_value2c 
}; 

Ensuite, vous ajoutez à votre hachage dans l'ensemble, se souvenant que Les structures perl imbriquées ne contiennent que des références aux autres structures.

$topHash{line1} = \%lineHash; 
$topHash{line2} = $lineHashRef; 

Mise à jour Exemple donné une boucle sur un tableau de données pour analyser

my %topHash; 
foreach my $i (0 .. $#data) { 
    my %tempHash; 
    // stuff here to parse $data[$i] and populate %tempHash 
    $topHash{"line$i"} = \%tempHash; 
} 
+0

Mon problème est que je ne sais pas combien de% lineHash j'ai besoin, car il est lié au nombre de lignes dans un CSV lu à l'exécution. – Mick

+1

Alors, quel est le problème? Vous pouvez dire '$ topHash {" line $ line "} = $ lineHashRef' et continuer à incrémenter' $ line' chaque fois que vous créez un hachage anonyme à partir d'une ligne de votre fichier CSV. – mob

3

Pour ajouter un hachage anonyme lors de l'exécution, attribuez comme vous le feriez un élément de hachage normal:

$HoH{key} = { foo => 42 }; 

ou

$HoH{key} = $hash_ref; 

ou

$HoH{key} = \%hash; 
1
#!/usr/bin/perl 

use strict; 

my %HoH = (
    line01 => { 
     cell01 => "cell0101", 
     cell02 => "cell0102", 
     cell03 => "cell0103" 
    } 
); 

$HoH{"line02"} = 
    { 
     cell01 => "cell0201", 
     cell02 => "cell0202", 
     cell03 => "cell0203" 
    }; 

foreach my $hohKey (keys %HoH) 
{ 
    my $newHash = $HoH{$hohKey}; 
    print "Line Name: $hohKey\n"; 
    foreach my $key (keys %$newHash) 
    { 
     print "\t$key => ", $newHash->{$key}, "\n"; 
    } 
} 
0

Chaque fois que vous créez un nouveau hachage à partir d'une ligne de données, vous aurez besoin de penser à une clé unique pour stocker ces données dans votre top table de hachage.

my $line = 1; 
my %HoH; 
while (<>) { 
    my ($cell01, $cell02, $cell03, @etc) = split /,/; 
    my $newHash = { cell01 => $cell01, cell02 => $cell02, ... }; 
    my $key = "line$line"; 
    $HoH{$key} = $newHash; 
    $line++; 
} 

Maintenant keys(%HoH) retourne une liste (non triés) comme "line1","line2","line3",....
$HoH{"line5"} renverrait une référence aux données pour la 5ème ligne de votre fichier.
%{$HoH{"line7"}} est une sorte de syntaxe moche, mais il renvoie une hashtable de vos données de la ligne 7.
$HoH{"line14"}{"cell02"} pourrait être utilisé pour obtenir une donnée spécifique.