Página 1 de 1

Cómo sumar multiples valores de múltiples hashes

NotaPublicado: 2016-07-18 22:00 @958
por kaptincho
Hola, amigos, estoy intentando sumar múltiples valores de múltiples hashes con la misma clave.

Este es el resultado que me gustaría obtener:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. HASH1 => { '2016-07-01' => { 'val1' => '7', 'val2' => '9', }, '2016-07-02' => { 'val1' => '10', 'val2' => '2', } }
  2. HASH2 => { '2016-07-01' => { 'val1' => '8', 'val2' => '4', }, '2016-07-03' => { 'val1' => '3', 'val2' => '2', } }
  3. HASH3 => { '2016-07-01' => { 'val1' => '6', 'val2' => '5', }, '2016-07-02' => { 'val1' => '1', 'val2' => '6', }, '2016-07-04' => { 'val1' => '4', 'val2' => '2', } }
  4.  
  5. SALIDA:
  6. HASH => { '2016-07-01' => { 'val1' => '21', 'val2' => '18', }, '2016-07-02' => { 'val1' => '11', 'val2' => '8', }, '2016-07-03' => { 'val1' => '3', 'val2' => '2', }, '2016-07-04' => { 'val1' => '4', 'val2' => '2', }, }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Aquí mi intento de código para realizar la operación:

Empujo todas las claves duplicadas a un array para identificarlas y luego sumar los valores.

En este ejemplo estoy comparando 2 hashes, pero me gustaría hacerlo con múltiples. Ejemplo 3 en la misma función:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. my @common = (); 
  2. foreach (keys %HASH1) { 
  3.     push(@common, $_) if exists $HASH2{$_}; 
  4. foreach my $DUP_KEY (@common){ 
  5.     my $v1 = $HASH1{$DUP_KEY}{'val1'} + $HASH2{$DUP_KEY}{'val1'}; 
  6.     my $v2 = $HASH1{$DUP_KEY}{'val2'} + $HASH2{$DUP_KEY}{'val2'}; 
  7.     $HASH1{$DUP_KEY}{'val1'} = $v1; 
  8.     $HASH1{$DUP_KEY}{'val2'} = $v2; 
  9.  
  10. my %OUT_HASH = (%HASH1, %HASH2); 
  11.  
  12. foreach my $key (keys %OUT_HASH) { 
  13.     push(@ARR, $key); 
  14. foreach (sort @ARR) { 
  15.     push(@ARR_CLEAN, $_); 


Pero el resultado no es el esperado porque si repito el proceso con el HASH3 no me toma los valores de HASH2 en el hash de salida.

No doy con la operación correcta.

¿Alguien podría guiarme mejor? ¡Gracias!

Re: Cómo sumar multiples valores de multiples hashes?

NotaPublicado: 2016-07-19 00:38 @068
por kaptincho

Re: Cómo sumar multiples valores de múltiples hashes

NotaPublicado: 2016-07-19 10:37 @484
por explorer
Esta es mi versión, usando each() en lugar de recorrer las claves.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. use v5.14;
  3.  
  4. my $HASH1 = { '2016-07-01' => { 'val1' => '7', 'val2' => '9', }, '2016-07-02' => { 'val1' => '10', 'val2' => '2', } };
  5. my $HASH2 = { '2016-07-01' => { 'val1' => '8', 'val2' => '4', }, '2016-07-03' => { 'val1' => '3', 'val2' => '2', } };
  6. my $HASH3 = { '2016-07-01' => { 'val1' => '6', 'val2' => '5', }, '2016-07-02' => { 'val1' => '1', 'val2' => '6', }, '2016-07-04' => { 'val1' => '4', 'val2' => '2', } };
  7.  
  8. my $HASH_OUT;
  9.  
  10. for my $hash_ref ( $HASH1, $HASH2, $HASH3 ) {
  11.    
  12.     while (my($clave, $subhash_ref) = each %$hash_ref) {
  13.    
  14.         while (my($subclave, $valor) = each %$subhash_ref) {
  15.        
  16.             $HASH_OUT->{$clave}->{$subclave} += $valor;
  17.         }
  18.     }
  19. }
  20.  
  21. use Data::Dumper;
  22. say Dumper $HASH_OUT;
  23.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Como ves, es más simple (no hay tantos '$').

Lo que hacemos es recorrer los hashes con dos niveles de profundidad, y el hash con el resultado va acumulando los valores. Debido a que los hashes en Perl tienen la propiedad de la autovivificación, se van creando entradas en el hash de salida, de forma automática.