Pregunta

Intentaré ilustrar esto con un ejemplo. Tome un ejemplo común de Hash of Hashes:

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

Para mis propósitos, me gustaría poder agregar hashes anónimos o sin nombre a% HOH. No necesitaré (o seré capaz de) definir estos sub-hash hasta el tiempo de ejecución. ¿Cómo puedo lograr esto con Perl?

Todo lo que he leído (y ya lo he leído a través de Perldocs y Google'd) parece mostrar ejemplos en los que se definen todos los sub-hahes (por ejemplo, "picapiedras", "jetsons" y "simpsons") .

Lo que estoy haciendo es intentar construir un Hash primario que contendrá subhits con filas de un archivo 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

    );

El número de "% LineX " los hashes que necesito no se conocen hasta el tiempo de ejecución (porque representan el número de líneas en un CSV que se lee en tiempo de ejecución).

¿Alguna idea? Si aún no está claro ... todavía estoy tratando de entender los hash de Perl.

¿Fue útil?

Solución

Primero crea el hash desde la línea actual que está analizando

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

o crear una referencia a un hash directamente

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

Luego lo agrega a su hash general, recordando que las estructuras perl anidadas solo contienen referencias a las otras estructuras.

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

Actualizado Ejemplo dado un bucle sobre una matriz de datos para analizar

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

Otros consejos

Para agregar un hash anónimo en tiempo de ejecución, asígnelo como lo haría con un elemento hash normal:

$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";
    }
}

Cada vez que cree un nuevo hash a partir de una línea de datos, deberá pensar en una clave única para almacenar esos datos en su tabla de hash superior.

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++;
}

Ahora las teclas (% HoH) devolverán una lista (sin clasificar) como " line1 ", " line2 ", " line3 ", ... .
$ HoH {" line5 "} devolvería una referencia a los datos de la quinta línea de su archivo.
% {$ HoH {" line7 "}} es una sintaxis fea pero devuelve una tabla hash de sus datos de la línea 7.
$ HoH {" line14 "} {" cell02 "} podría usarse para obtener un dato específico.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top