Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 
Índice general » Mundo Perl » Intermedio » Duplicar hash con éxito Responder al tema


Página 1 de 1  [ 4 mensajes ] 
 
Nota Vie Jul 03, 2009 5:15 am

Perlero Nuevo
Registrado: Mar Abr 14, 2009 2:23 am
Mensajes: 9
Duplicar hash con éxito
Hola.

Trato de duplicar un hash de arrays (%fichero1), porque tengo que recorrerlo dos veces haciendo shift() sobre los elementos de los arrays hasta que queda uno, y al final un delete() sobre la key.

El problema es que, como tengo que hacer esto dos veces sobre el mismo hash, pues se me han ocurrido dos opciones, ninguna de las cuales me funciona por motivos que desconozco.

El programa es extensísimo, así que a ver si puedo sintetizar lo importante. Del %fichero2 nos podemos olvidar, que no interesa para la cuestión.

Opción 1:

Pasar la primera vez el array a la función (que realiza los shift() y el delete()) por valor, en lugar de por referencia. Así la primera vez trabajo sobre una copia y la segunda ya puedo eliminar los datos sobre el original:
Sintáxis: [ Descargar ] [ Ocultar ]
Usando Coloreado de perl
funcion(%fichero1,\%fichero2);
funcion(\%fichero1,\%fichero2);


Esto me da un error que traducido viene a decir que "no se pueden utilizar falsos hashes". Creo que no se pueden pasar hashs por valor, corregidme si me equivoco.

Opción 2:
Sintáxis: [ Descargar ] [ Ocultar ]
Usando Coloreado de perl
my %fichero1_copia = %fichero1;
use Data::Dumper;
print Dumper \%fichero1;
funcion(\%fichero1,\%fichero2);
print "\n---------------\n";
print Dumper \%fichero1;
print Dumper \%fichero1_copia;
funcion(\%fichero1_copia,\%fichero2);


Esta segunda opción pretendía que el segundo Dumper saliera vacío y el tercero lleno... pero en su lugar obtengo esto:

Código:
$VAR1 = {
          'c3' => [
                      [
                        50,
                        52,
                        'CO',
                        '+'
                      ]
                    ],
          'c1' => [
                      [
                        20,
                        22,
                        'COL',
                        '+'
                      ],
                      [
                        10,
                        12,
                        'COL',
                        '+'
                      ],
                      [
                        30,
                        32,
                        'COL',
                        '+'
                      ],
                      [
                        80,
                        82,
                        'COL',
                        '+'
                      ],
                      [
                        90,
                        92,
                        'COL',
                        '+'
                      ]
                    ],
          'c2' => [
                      [
                        40,
                        42,
                        'COM',
                        '+'
                      ],
                      [
                        210,
                        32,
                        'COM',
                        '+'
                      ]
                    ]
        };

---------------

$VAR1 = {};

$VAR1 = {
          'c3' => [
                      [
                        50,
                        52,
                        'CO',
                        '+'
                      ]
                    ],
          'c1' => [
                      [
                        90,
                        92,
                        'COL',
                        '+'
                      ]
                    ],
          'c2' => [
                      [
                        210,
                        32,
                        'COM',
                        '+'
                      ]
                    ]
        };


No entiendo por qué %fichero1_copia no tiene todos los elementos originales. Y si es que los hashs nunca hacen copia, sino que se duplican por referencia (lo que no me sirve), ¿por qué tiene sólo los elementos finales del hash original, en lugar de estar vacío, como el hash original tras ejecutar la función? Es como si los shift() hubieran tenido efecto pero los delete() de las keys no.

En fin... un mar de dudas, espero no haber complicado demasiado mi cuestión. Para simplificar, mi pregunta principal es "cómo duplicar un hash con todo su contenido para trabajar con original y copia de manera independiente".

Un saludo.


Nota Vie Jul 03, 2009 3:26 pm

Perlero Frecuente
Registrado: Dom May 04, 2008 1:11 am
Ubicación: Ciudad del Este, Paraguay
Mensajes: 133
Re: Duplicar hash con éxito
Creo que tu problema está en la subrutina. Hice un ejemplo para comprobarlo:
Sintáxis: [ Descargar ] [ Ocultar ]
Usando Coloreado de perl
use strict;
use warnings;
use Data::Dumper;

my %hash = (
    a    => ["jose", "maria", "carlos"],
    b    => ["12", "15", "13"],
    c    => ["cabello", "brazos", "piernas"],
);

my %duplicado_hash = %hash;

print "Original antes de la subrutina:\n", Dumper(\%hash);
hacer(\%hash);
print "Duplicado después de la subrutina:\n", Dumper(\%duplicado_hash);


sub hacer{
 my %h = shift;
# my %h = %{$_[0]};
        while (my ($llave, $valor) =  each %h) {
                while (my $b = shift @{$valor}){
                        # Aquí retorna valores a $b, obtenidos por medio de shift
                }
        }
}


Yo utilicé shift. Si te fijas en el código, y reemplazas shift por %{$_[0]}, te darás cuenta que habrá cambios.

_________________
With Perl
Imagination is more important than knowledge. Albert Einstein.


Nota Vie Jul 03, 2009 7:55 pm
Avatar de Usuario
Administrador
Registrado: Dom Jul 24, 2005 6:12 pm
Ubicación: Valladolid, España
Mensajes: 6217
Re: Duplicar hash con éxito
Para copiar estructuras complejas, existe el módulo Clone, que realiza esa tarea de forma muy cómoda:

Sintáxis: [ Descargar ] [ Ocultar ]
Usando Coloreado de perl
use Clone qw(clone);

%x = ( a=> [ 1, 2, 3], b => [ 4, 5, 6 ] );

%y = %{ clone(\%x) };

use Data::Dumper;
print Dumper \%y;

_________________
JF^D Perl programming


Nota Sab Jul 04, 2009 7:16 pm

Perlero Frecuente
Registrado: Lun Oct 29, 2007 6:31 am
Ubicación: Praga, Republica Checa
Mensajes: 132
Re: Duplicar hash con éxito
Lo más sencillo sería cambiar el código para que no destruye el hash.

while (my $item = shift(@array) {

por

for my $item (@array) {

y

while (my ($key, $value) = each %hash) {

por

foreach my $key (keys %hash) {

_________________
-------------------------------------------------------
- Estoy aquí para practicar español. Si te ayudó mi respuesta ayudame con un mensaje privado sobre mis faltas por favor. Seguramente habrá muchas :-)


Responder al tema  [ 4 mensajes ] 

Reglas del Foro
No puede abrir nuevos temas en este Foro
No puede responder a temas en este Foro
No puede editar sus mensajes en este Foro
No puede borrar sus mensajes en este Foro
No puede enviar adjuntos en este Foro

Publicidad

Socializa

Síguenos por Twitter

Suscríbete GRATUITAMENTE al Boletín de Perl en Español

Saltar a:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Traducción al español por Huan Manwë
phpBB SEO