Come posso creare e aggiungere hash anonimi a un hash noto durante l'esecuzione dello script?
-
10-07-2019 - |
Domanda
Tenterò di illustrarlo con un esempio. Prendi un esempio comune di Hash of Hash:
my %HoH = (
flintstones => {
lead => "fred",
pal => "barney",
},
jetsons => {
lead => "george",
wife => "jane",
"his boy" => "elroy",
},
simpsons => {
lead => "homer",
wife => "marge",
kid => "bart",
},
);
Ai miei scopi, vorrei poter aggiungere un hash anonimo o anonimo a% HOH. Non avrò bisogno (o non sarò in grado di) definire questi hash secondari fino al runtime. Come posso ottenere questo risultato con Perl?
Tutto ciò che ho letto (e ho già letto su Perldocs e su Google già) sembra mostrare esempi in cui sono definiti tutti i sub-hahes (ad es. "flintstones", "jetsons", e "simpsons") .
Quello che sto facendo è il tentativo di creare un hash padre che conterrà degli hash secondari con righe da un file 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
);
Il numero di "% LineX " gli hash di cui ho bisogno non sono noti fino al runtime (perché rappresentano il numero di righe in un CSV che viene letto in fase di runtime).
Qualche idea? Se non è già chiaro ... Sto ancora cercando di avvolgere la testa attorno agli hash di Perl.
Soluzione
Per prima cosa crei l'hash dalla riga corrente che stai analizzando
my %lineHash = (
cell01 => $some_value1a,
cell02 => $some_value1b,
cell03 => $some_value1c
);
o crea un riferimento a un hash definitivo
my $lineHashRef = {
cell01 => $some_value2a,
cell02 => $some_value2b,
cell03 => $some_value2c
};
Quindi lo aggiungi al tuo hash complessivo, ricordando che le strutture perl nidificate contengono solo riferimenti alle altre strutture.
$topHash{line1} = \%lineHash;
$topHash{line2} = $lineHashRef;
Esempio dato un ciclo su una matrice di dati da analizzare
my %topHash;
foreach my $i (0 .. $#data) {
my %tempHash;
// stuff here to parse $data[$i] and populate %tempHash
$topHash{"line$i"} = \%tempHash;
}
Altri suggerimenti
Per aggiungere un hash anonimo in fase di runtime, assegnalo come faresti con un normale elemento hash:
$HoH{key} = { foo => 42 };
o
$HoH{key} = $hash_ref;
o
$HoH{key} = \%hash;
#!/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";
}
}
Ogni volta che crei un nuovo hash da una linea di dati, dovrai pensare a una chiave univoca per archiviare quei dati nella tua tabella hash in alto.
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++;
}
Ora chiavi (% HoH)
restituirà un elenco (non ordinato) come " line1 ", " line2 ", " line3 ", ...
.
$ HoH {" line5 "}
restituirebbe un riferimento ai dati per la 5a riga del tuo file.
% {$ HoH {" line7 "}}
è una specie di brutta sintassi ma restituisce un hashtable dei tuoi dati
dalla linea 7.
$ HoH {" line14 "} {" cell02 "}
potrebbe essere utilizzato per ottenere un dato specifico.