Como faço para criar e adicionar hashes anônimos a um Hash conhecido durante a execução do script?

StackOverflow https://stackoverflow.com/questions/1645080

Pergunta

Vou tentar ilustrar isto com um exemplo. Vejamos um exemplo comum de um Hash de hashes:

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

Para os meus propósitos, eu gostaria de ser capaz de adicionar um hashes sem nome, ou anônimos% HOH. Não será necessário (ou ser capaz de) definir estas sub-hash até a execução. Como posso fazer isso com Perl?

Tudo o que eu li (e eu li através Perldocs e Google'd já) parece mostrar exemplos em todas as sub-hahes (por exemplo, "Flintstones", "Jetsons", e "simpsons") são definidos.

O que estou fazendo é tentando construir um Hash pai que conterá sub-hashes com linhas de um arquivo 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

    );

O número de "% Linex" hashes que eu preciso não é conhecido até a execução (porque eles representam o número de linhas em um arquivo CSV que é lido em tempo de execução).

Todas as idéias? Se ainda não estiver claro ... Eu ainda estou tentando envolver minha cabeça em torno de hashes Perl.

Foi útil?

Solução

Primeiro você cria o hash a partir da linha atual que você está parsing

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

ou criar uma referência a um hash outright

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

Em seguida, você adicionar ao seu haxixe geral, lembrando que as estruturas perl aninhados apenas conter referências a outras estruturas.

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

Atualização Exemplo dado um laço sobre uma matriz de dados para analisar

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

Outras dicas

Para adicionar um hash anônimo em tempo de execução, atribuí-lo como se fosse um elemento de hash normal:

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

ou

$HoH{key} = $hash_ref;

ou

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

Toda vez que você criar um novo hash a partir de uma linha de dados, você precisa pensar em uma chave única para armazenar os dados na sua tabela topo hash.

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

Agora keys(%HoH) retornará uma lista (sem classificação) como "line1","line2","line3",....
$HoH{"line5"} retornaria uma referência aos dados para a 5ª linha do seu arquivo.
%{$HoH{"line7"}} é uma espécie de sintaxe feio, mas ele retorna uma tabela hash de seus dados da linha 7.
$HoH{"line14"}{"cell02"} poderia ser usado para chegar a uma parte específica de dados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top