• Publicidad

Hash de dimensiones múltiples

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Hash de dimensiones múltiples

Notapor xagutxu_perez » 2008-06-08 15:00 @667

Hola a todos.

Tengo un hash compuesto de (valor, array de elementos). ¿Cómo puedo obtener un array de elementos correspondiente a un valor concreto? Supongamos que el valor es "marmitako" y su array correspondiente: (patata,atún,tomate,cebolla).

He intentado hacer así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @correct_zerrenda = @corpusa{correct};
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Pero no sirve.

He visto en el tutorial que podemos acceder a un elemento del array así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
print $hash{"Café Colombiano"}[1];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Pero cómo podría acceder a todos?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $elem (%hash)
     print $hash{"Café Colombiano"}[]
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Así no, ¿no? Porque no funciona...

Gracias a todos,

Xagutxu
xagutxu_perez
Perlero nuevo
Perlero nuevo
 
Mensajes: 43
Registrado: 2008-04-04 03:56 @206

Publicidad

Notapor elnico » 2008-06-08 15:41 @695

Hola.
Usa esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
for(my $i=0; $i<2; $i++){
 print "ELEMENTO: ".$hash{'Café Colombiano'}[$i]." \n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
elnico
Perlero nuevo
Perlero nuevo
 
Mensajes: 69
Registrado: 2007-09-09 14:44 @656

Otro problema...

Notapor xagutxu_perez » 2008-06-08 15:52 @702

Pues he probado lo que me has dicho, pero sale un error en el "for":

Código: Seleccionar todo
Operation "<": no method found,
        left argument has no overloaded magic,
        right argument in overloaded package XML::LibXML::NodeList at erabaki_zuhaitzak.pl line 243.


Estoy utilizando, como se ve, el XML::LibXML, y no sé si hace alguna interferencia...
xagutxu_perez
Perlero nuevo
Perlero nuevo
 
Mensajes: 43
Registrado: 2008-04-04 03:56 @206

Notapor explorer » 2008-06-08 16:56 @747

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;

my %hash = (
    marmitako   => [qw( patata atún tomate cebolla )],
);

my @seleccion = @{$hash{marmitako}};
print ":> @seleccion\n";

my @otra_seleccion = @{ $hash{marmitako} } [1,3];
print ":> @otra_seleccion\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Es recomendable leer perldata, perldsc, acceso a Hash de Arrays y perllol, Slices, que es de donde he sacado el último ejemplo, aunque recomienda no usarlo, porque es más difícil de leer que si hubiéramos puesto un bucle.

Lo académico sería
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $i ( 0 .. $#{$hash{marmitako}} ) {
    print $hash{marmitako}[$i], "\n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

o
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $elemento ( @{$hash{marmitako}} ) {
    print "$elemento\n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Hash a subrutina

Notapor xagutxu_perez » 2008-06-09 15:50 @701

Gracias como siempre, Explorer. Ya sabes, "después de visto..."

Tengo otro problemita: ¿Es posible pasar un hash a una subrutina?

Tengo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
&su_calcular(%corpus, $contador);
#...
sub su_calcular{
        my %corpus = shift;
        my $contador = shift;
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Imprimo, dentro de la subrutina, el %corpus:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
                foreach my $elem (sort keys %corpusa) {
                        print "$elem: @{$corpusa{$elem}}\n";
                }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y obtengo el error:
Código: Seleccionar todo
"Can't use an undefined value as an ARRAY reference at file.pl line 337."


¿Es por que estoy pasando mal el hash a la subrutina?

Gracias,

Xagutxu
xagutxu_perez
Perlero nuevo
Perlero nuevo
 
Mensajes: 43
Registrado: 2008-04-04 03:56 @206

Notapor explorer » 2008-06-09 16:35 @732

Intercambia el orden de los parámetros.

Resulta que los array y los hash son 'expandidos' en todos sus elementos, cuando los pasas por valor, por lo que, a efectos prácticos, le están pasando todas las parejas clave/valor como si fuera una lista de valores. Luego, dentro de la función, intentas volver a leer el hash, pero Perl no sabe que $contador forma parte de una variable aparte, y en su lugar cree que se trata de una clave más del hash que se pasó. Por eso se mete en %corpus. Y $contador se queda sin valor.

Pero intercambiando los argumentos, arreglas este problema, porque primero obtienes el valor de $contador, y luego ya sabes que todos los elementos que le siguen, tomados de dos en dos, son las claves/valor del hash.

Otra opción, mejor, es pasar todos los argumentos por referencia.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
su_calcular(\%corpus, $contador);

#...

sub su_calcular{
    my $corpus_ref = shift;
    my $contador   = shift;

    foreach my $elem (sort keys %$corpus_ref) {
        print "$elem: @{$corpus_ref->{$elem}}\n";
    }
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Más información en perlsub.

P.D. Realmente, al hacer un 'shift', en tu función, solo estás leyendo el primer valor del hash (la primera clave), y luego, el siguiente 'shift' mete el valor de esa clave en contador.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor xagutxu_perez » 2008-06-09 16:47 @741

¿Y cómo puedo reconstruir el hash con el foreach?
xagutxu_perez
Perlero nuevo
Perlero nuevo
 
Mensajes: 43
Registrado: 2008-04-04 03:56 @206

Notapor explorer » 2008-06-09 16:52 @744

Te lo he puesto de ejemplo. Pasándolo como referencia, hay que referirse a él como una referencia, por lo que hay que desreferenciarla en caso de querer acceder a los elementos. Mira el ejemplo que te he puesto.

También puedes hacer una copia:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my %corpus = %$corpus_ref;
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor xagutxu_perez » 2008-06-09 17:42 @779

¡Uauu!

Todo bien, aunque tengo que mirar bien la documentación de perlsub, porque me queda un poco grande...

¡Gracias, explorer!
xagutxu_perez
Perlero nuevo
Perlero nuevo
 
Mensajes: 43
Registrado: 2008-04-04 03:56 @206


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron