• Publicidad

Duplicar hash con éxito

¿Ya sabes lo que es una referencia? Has progresado, el nível básico es cosa del pasado y ahora estás listo para el siguiente nivel.

Duplicar hash con éxito

Notapor gorkalinux » 2009-07-03 05:15 @260

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 ]
Using perl Syntax Highlighting
funcion(%fichero1,\%fichero2);
funcion(\%fichero1,\%fichero2);
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


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 ]
Using perl Syntax Highlighting
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);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


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: Seleccionar todo
$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.
gorkalinux
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2009-04-14 02:23 @141

Publicidad

Re: Duplicar hash con éxito

Notapor netsoul » 2009-07-03 15:26 @684

Creo que tu problema está en la subrutina. Hice un ejemplo para comprobarlo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
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
                }
        }
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


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.
netsoul
Perlero nuevo
Perlero nuevo
 
Mensajes: 150
Registrado: 2008-05-04 01:11 @091

Re: Duplicar hash con éxito

Notapor explorer » 2009-07-03 19:55 @871

Para copiar estructuras complejas, existe el módulo Clone, que realiza esa tarea de forma muy cómoda:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use Clone qw(clone);

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

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

use Data::Dumper;
print Dumper \%y;
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: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Duplicar hash con éxito

Notapor Jenda » 2009-07-04 19:16 @844

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 :-)
Jenda
Perlero nuevo
Perlero nuevo
 
Mensajes: 132
Registrado: 2007-10-29 06:31 @313
Ubicación: Praga, Republica Checa


Volver a Intermedio

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 21 invitados

cron