strawberry - perl tutorial
Perl ¿Cómo recupero una matriz de un hash de matrices? (4)
"¿Por qué solo está pegando el primer valor de la matriz?"
Necesitas poner una referencia a tu matriz en el hash prefijándolo con una barra invertida:
$HoA{$key} = /@testarray;
Luego, cuando lo recuperas del hash, desentendes:
@testarray = @{ $HoA{$key} };
Soy bastante nuevo en Perl, así que perdóname si esto parece una pregunta simple ...
De todos modos, tengo un hash de arreglos y estoy tratando de recuperar uno de los arreglos en el hash, pero todo lo que puedo obtener es el tamaño escalar del arreglo.
%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 tiene el tamaño de la matriz y el bucle solo se ejecuta una vez. He intentado imprimir lo siguiente:
@HoA{$key}
$HoA{$key}
@$HoA{$key}
Los dos primeros me dan el tamaño del escalar y el tercero no me da nada ... ¿qué me estoy perdiendo aquí?
ACTUALIZACIÓN: Me pregunto si mi problema es en realidad la forma en que estoy agregando los arreglos al hash. Esto es lo que estoy haciendo:
@HoA{$key} = split(/ /, $list);
¿Eso pega la matriz en el hash, o el tamaño de la matriz en el hash?
ACTUALIZACIÓN 2: Probé el siguiente bloque de código:
my $key = "TEST";
my %HoA = ();
my @testarray = (1, 2, 3);
@HoA{$key} = @testarray;
print Dumper(%HoA);
Aquí está la salida:
$VAR1 = ''TEST'';
$VAR2 = 1;
¿Por qué solo está pegando el primer valor de la matriz en?
Cada entrada en su hash es una referencia a una matriz. Por ejemplo:
$my_hash{$key}
es una referencia a una matriz y no a una matriz. $my_hash{$key}
simplemente apunta a un área en la memoria donde vive la matriz. Para desreferenciarlo, coloca el símbolo de la matriz en frente:
@{ my_hash{$key} }
Las cosas se ponen un poco más peludas cuando empezamos a hablar sobre los elementos:
${ my_hash{$key} }[0]
Es el primer elemento de esa matriz. Se puede imaginar que si la matriz estuviera formada por hashes a otras matrices, la sintaxis puede ser bastante obstruida. Afortunadamente, Perl tiene una forma limpia de manejarlo:
$my_hash{$key}->[0];
Es exactamente lo mismo que arriba, pero es más fácil de entender la sintaxis. A veces, es más fácil usar variables intermedias solo para que puedas referirte a las cosas sin tener que desreferenciarlas:
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 desreferenciación obtienes esto:
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";
}
}
Intente hacer referencia a su matriz 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
}
Toma la referencia de matriz en $HoA{$key}
y $HoA{$key}
en una matriz.
Edit: Para tu actualización, creo que obtendrás lo que quieres, si lo haces de esta manera:
@{$HoA{$key}} = split(/ /, $list);
o puedes hacer
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: Añadir use strict;
a la cima de tu programa. Básicamente, estás intentando usar HoA como una matriz cuando tienes un hash definido. Estás haciendo referencia a los contenidos de tu hash de forma incorrecta. Para hacerlo correctamente, realmente necesitas tener un $
entre @
y HoA
. Perl no tiene tipo y le permitirá salirse con la suya si no use strict;
. Un extracto de referencia de 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 una referencia a una matriz
@{$hash{$el1}} = @array
es un elemento hash que contiene una matriz
@array
Es como 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, por lo que
@{ $HoA{$key} }
es esa matriz
for my $nextItem (@{ $HoA{$key} })