2012-09-21 14 views
14

Soy bastante nuevo en Perl, así que discúlpeme si esto parece una simple pregunta ...Perl ¿Cómo recupero una matriz de un hash de matrices?

De todos modos, tengo un hash de matrices y estoy tratando de recuperar una de las matrices en el hash, pero todo lo que puedo obtener es el tamaño escalar de la matriz.

%HoA = a hash of arrays 
$key = some key in the hash 

foreach $nextItem (@HoA{$key}) { 
    do a bunch of stuff with $nextItem 
} 

Cuando hago esto, $ nextItem siempre es sólo el tamaño de la matriz y el bucle sólo se ejecuta a través de una sola vez. He intentado imprimir la siguiente:

@HoA{$key} 
$HoA{$key} 
@$HoA{$key} 

Los dos primeros dame el tamaño escalares y la tercera me da nada ... lo que me estoy perdiendo aquí?

ACTUALIZACIÓN: Me pregunto si mi problema es realmente la forma en que estoy agregando las matrices al hash. Esto es lo que estoy haciendo:

@HoA{$key} = split(/ /, $list); 

¿Eso se pega la matriz en el hash, o el tamaño de la matriz en el hash?

ACTUALIZACIÓN 2: Me trató el siguiente bloque de código:

my $key = "TEST"; 
my %HoA =(); 
my @testarray = (1, 2, 3); 
@HoA{$key} = @testarray; 
print Dumper(%HoA); 

está la salida Aquí:

$VAR1 = 'TEST'; 
$VAR2 = 1; 

¿Por qué sólo pegando el primer valor de la matriz en?

Respuesta

13

Trate incluir su gama de esta manera:

%HoA = a hash of arrays 
$key = some key in the hash 

foreach $nextItem (@{$HoA{$key}}) { 
    do a bunch of stuff with $nextItem 
} 

usted toma la referencia de matriz en $HoA{$key} y lo convierten en una matriz.

Editar: Para su actualización, creo que va a conseguir lo que quieres, si lo haces de esta manera:

@{$HoA{$key}} = split(/ /, $list); 

o puede hacerlo

push(@{$HoA{$key}}, split(/ /, $list); 

Por ejemplo:

my $list = "fred joe brown sam"; 
my %HoA =(); 
my $key = "jacob"; 
@{$HoA{$key} = split(/ /, $list); 
foreach my $item (@{$HoA{$key}}) 
{ 
    print "Test item: $nextItem\n"; 
} 

You will get: 
Test item: fred 
Test item: joe 
Test item: brown 
Test item: sam 

Editar: Agregue use strict; al principio de su programa. Básicamente está intentando usar HoA como una matriz cuando tiene un hash definido. Estás haciendo referencia al contenido de tu hash incorrectamente. Para hacerlo correctamente realmente necesita tener un $ entre @ y HoA. Perl no tiene palabras y te dejará salir impune si no lo haces use strict;. Un reference excerpt from oreilly podría aclarar algunas cosas.

my @testarray es una matriz
my %hash es un hash
$hash{$el1} = \@array es un elemento hash que tiene el valor de un ref a una matriz
@{$hash{$el1}} = @array es un elemento hash que contiene una matriz

+0

he intentado . Simplemente devuelve un tamaño de cero y el bucle ni siquiera se ejecuta una vez. – mrplainswalker

+0

@mrplainswalker - Intente imprimir el contenido del hash y asegúrese de que tenga la estructura que cree que tiene. Quizás tu clave no está definida o no es una matriz como crees. Puedes usar Data :: Dumper; Dumper (% HoA) para verificarlo.También puedes hacer if (defined ($ HoA {$ key})) {print "Defined"} como una prueba rápida también – scrappedcola

+0

Ok, probé la función Dumper para ver lo que había en el hash, y tienes razón. ..no es lo que esperaba. Cada valor es solo el primer elemento de la matriz en lugar de la matriz completa. – mrplainswalker

2
@array 

Es cómo se obtiene la matriz, por lo que

@{ $array_ref } 

es el equivalente con una referencia de matriz.

$HoA{$key} 

es una referencia a una matriz, de modo

@{ $HoA{$key} } 

es que array.

for my $nextItem (@{ $HoA{$key} }) 
6

Cada entrada en el hash es una referencia a una matriz. Por ejemplo:

$my_hash{$key} 

es una referencia a una matriz y no una matriz. $my_hash{$key} está simplemente apuntando a un área en la memoria donde vive esa matriz. Para eliminar la referencia, se pone el símbolo de matriz delante:

@{ my_hash{$key} } 

Las cosas se ponen un poco más peludo cuando empezar a hablar de los elementos:

${ my_hash{$key} }[0] 

es el primer elemento de la matriz. Se puede imaginar si esa matriz consistía en hashes a otras matrices, la sintaxis puede ser bastante obstinada. Afortunadamente, Perl tiene una forma limpia de manejarla:

$my_hash{$key}->[0]; 

Eso es exactamente el mismo que el anterior, pero más fácil de entender la sintaxis. A veces, es más fácil de utilizar variables intermedias sólo para que pueda referirse a cosas sin toda la eliminación de referencias:

my %hash_of_array_refs; 

foreach my $key (sort keys %hash_of_array_refs) { 
    my @array = @{ $hash_of_array_refs{$key} }; #Dereference 
    foreach my $element (@array) {     #Much easier to read and understand 
     say "First element is $array[0]"; 
     say "last element is $array[$#array]"; 
     say "This element: $element"; 
    } 
} 

Sin eliminación de referencias se obtiene lo siguiente:

my %hash_of_array_refs; 

foreach my $key (sort keys %hash_of_array_refs) { 
    foreach my $element (@{ $hash_of_array_refs{$key} }) {     #Much easier to read and understand 
     say "First element is " . $hash_of_array_refs->[0]; 
     say "last element is " . $hash_of_array_refs->[$#{ $hash_of_array_refs{key} } ]"; 
     say "This element: $element"; 
    } 
} 
+0

+1 ~ GRACIAS !! He consultado varios artículos y USTED es la primera persona en explicar cómo acceder a un elemento dentro de un hash de matrices utilizando $ myhash {$ key} -> [0]. –

0

"¿Por qué es que sólo sobresale el primer valor de la matriz en? "

Es necesario poner una referencia a su matriz en el hash prefijándolo con una barra invertida:

$HoA{$key} = \@testarray; 

Luego, cuando la recupere de la hash que eliminar la referencia:

@testarray = @{ $HoA{$key} }; 
+0

Cierto, ¿pero esto no ha sido ya señalado en las otras respuestas? No estoy seguro de lo que su respuesta agrega aquí. –

+0

Las otras respuestas asumieron que ya tenía referencias en el hash y no resolvieron el problema de tratar de poner una matriz en un hash sin hacer referencia. Otras respuestas han sido editadas desde entonces. – RobEarl

Cuestiones relacionadas