• Publicidad

Problemas con un hash

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

Problemas con un hash

Notapor fgalves » 2006-10-12 05:10 @257

Hola a todos,

A ver si alguien me ayuda pues tengo ya la cabeza como un chorizo de cantimpalos:

Tengo un hash determinado con información en su interior organizada tal y como sigue:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
%Summary =
( 'AAAAcontador1' => 333,
   'BBBBcontador3' => 344,
   'AAAAHash' => {  #otro hash con mas hashes en su interior
                           }
   'CCCCcontador5' => 566,
   'AAAAcontador3' =>32,
   'BBBBHash' => ....
)
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Osea, tenemos para AAAA (que es un identificador), una serie de contadores, y un hash conteniendo información. Lo mismo para BBBB y CCCC, y así succesivamente. En mi hash anterior (%Summary), la llave es la concatenación del identificador (AAAA, BBBB, CCCC, ....) con el respectivo contador o hash.

Lo que yo quiero obtener es lo siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
%newSummary =
( 'AAAA' => { 'AAAAcontador1' => 333,
                     'AAAAHash' => { #otro hash con mas hashes},
                     'AAAAcontador3' =>32,
                      ....
                   }
  'BBBB' => { 'BBBBcontador3' => 344,
                     'BBBBHash' => { #otro hash con mas hashes},
                    ....
                   }
 y asi sucesivamente
)
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Es decir, crear un nivel superior en el que la llave es el identificador, y a un nivel inferior, pueda encontrar lo que tenía antes en %Summary. Lo que habré conseguido es clasificar por identificador.

¿Alguien tiene una idea simple pero eficiente de cómo hacerlo?

¡¡Muchisimas gracias!!
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Publicidad

Aclaración: lo que tenía en mente

Notapor fgalves » 2006-10-12 05:19 @263

Os pongo lo que tenía empezado pero me da muchos quebraderos de cabeza y no me aclaro:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
while(($key, $value) = each(%Summary))
{  ($identificador) = $key =~ /^([A-Z]+)/;
     if ($identificador =~ /^([A-Z]+)H/ ) {$identificador = $1;}

     $newSummary{$reportName} = .....
}
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Gracias a todos por vuestra ayuda,
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Notapor explorer » 2006-10-12 06:25 @309

Aquí hay un problema que puede ser muy complicado. Queremos reproducir una estructura en otra, pero no estamos seguros de a cuánta profundidad puede llegar esa primera estructura.
Podríamos hacer alguna función recursiva que fuera creando la copia de la estructura a medida que fuésemos recorriendo la primera.

Desde luego, otra solución sería colocar referencias a la antigua estructura, pero lo que se plantea en este problema es crear una nueva e independiente de la primera.

Existe un módulo que hace eso: sirve para copiar estructuras de datos en profundidad. Se trata de Clone. Con su ayuda, es muy fácil resolverlo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

use Clone 'clone';
use Data::Dumper::Names;
use warnings;
use strict;

my %Summary = (
    AAAAcontador1   => 333,
    BBBBcontador3   => 344,
    AAAAhash        => {
            clave1 => 1,
            clave2 => 2,
            clave3 => 3,
        },
    CCCCcontador5   => 566,
    AAAAcontador3   => 32,
    BBBBHash        => {
            clave1 => 10,
            clave2 => 20,
            clave3 => 30,
        },
);

my %NewSummary;

foreach my $clave_hash ( keys %Summary ) {

    my $clave = substr( $clave_hash, 0, 4 );

    $NewSummary{ $clave }{ $clave_hash } = clone( $Summary{ $clave_hash } );

}

print Dumper( \%NewSummary );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Código: Seleccionar todo
%NewSummary = (
                'AAAA' => {
                            'AAAAcontador1' => 333,
                            'AAAAcontador3' => 32,
                            'AAAAhash' => {
                                            'clave2' => 2,
                                            'clave3' => 3,
                                            'clave1' => 1
                                          }
                          },
                'BBBB' => {
                            'BBBBHash' => {
                                            'clave2' => 20,
                                            'clave3' => 30,
                                            'clave1' => 10
                                          },
                            'BBBBcontador3' => 344
                          },
                'CCCC' => {
                            'CCCCcontador5' => 566
                          }
              );
Explicación:
* Hacemos un recorrido por todo el hash, a través de sus claves.
* En vez de usar una expresión regular, he elegido usar substr ya que veo que todos los identificadores tienen 4 letras.
* Creamos diréctamente la nueva clave ( $NewSummary{ $clave }{ $clave_hash } ) y le asignamos una copia (clone) del valor correspondiente a esa clave en la anterior estructura. En unos casos esa copia no será más que un número (333), pero en otros será un hash entero.
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

Error en "use Clone"

Notapor fgalves » 2006-10-12 06:54 @329

¡Gracias por tus consejos y por tu código de ejemplo!
Desgraciadamente he añadido el "use Clone" y me da error.
Supongo que no estará disponible ya que no lo encuentra

Código: Seleccionar todo
Can't locate Clone.pm in @INC (@INC contains: ........


Gracias de todos modos
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Notapor explorer » 2006-10-12 07:07 @338

Claro, tienes que instalarlo...

De hecho, yo tampoco lo tenía en mi máquina, ni tampoco el módulo Data::Dumper::Names.

Pero no pasa nada. Ejecuté estos dos comandos:
Código: Seleccionar todo
cpan Clone
cpan Data::Dumper::Names
desde el shell y en menos de un minuto se los bajó de internet, compiló e instaló. Es una de las maravillas de Perl :-)

Tu sólo necesitarás el Clone, claro. A mi me gusta usar Data::Dumper y Data::Dumper::Names para estos casos de querer saber cómo son 'por dentro' las estructuras de datos :-D
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

¡¡gracias!!

Notapor fgalves » 2006-10-12 07:30 @354

¡¡Joer machos!! ¡¡¡Sois los mejores!!!
Este fin de semana os prometo una donación a la web porque me está resultando muy muy útil vuestra ayuda.
¡¡Un cordial saludo y gracias por vuestra rápida y certera ayuda!!
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621


Volver a Básico

¿Quién está conectado?

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

cron