2012-09-24 31 views
5

este es un volcado de mis hashes:% hash1Hash de combinación/concatenación

$VAR1 = { 
    abc => { 
     123 => [ 
      'xx', 
      'yy', 
      'zy' 
     ], 
     456 => [ 
      'ab', 
      'cd', 
      'ef' 
     ] 
    } 
}; 

y el segundo:% hash2

$VAR2 = { 
    def => { 
     659 => [ 
      'wx', 
      'yg', 
      'kl' 
     ], 
     456 => [ 
      'as', 
      'sd', 
      'df' 
     ] 
    }, 
    abc => { 
     987 => [ 
      'lk', 
      'dm', 
      'sd' 
     ] 
    } 
}; 

Ahora quiero fusionar estos dos valores hash en una nueva almohadilla , pero si una clave está duplicada (aquí 'abc'), los valores deben adjuntarse, no reemplazarse, por lo que las claves deben seguir siendo únicas, y todos los valores deben conservarse también. ¿Cómo se puede hacer esto en Perl? La salida debe ser como sigue:

módulos
$VAR1 = { 
    def => { 
     659 => [ 
      'wx', 
      'yg', 
      'kl' 
     ], 
     456 => [ 
      'as', 
      'sd', 
      'df' 
     ] 
    }, 
    abc => { 
     987 => [ 
      'lk', 
      'dm', 
      'sd' 
     ], 
     123 => [ 
      'xx', 
      'yy', 
      'zy' 
     ], 
     456 => [ 
      'ab', 
      'cd', 
      'ef' 
     ] 
    } 
}; 
+0

¿Me puede dar un ejemplo de datos fusionado estructura, por ejemplo entre '% a = (clave1 => {clave2 => [1]})' y '% b = (clave1 => {clave2 => [1]})'? No sé qué camino tomar cuando no sé hacia dónde voy. – amon

+0

He editado la pregunta principal con la salida necesaria, ¡Gracias por la ayuda! –

Respuesta

4
for my $x (keys(%h2)) { 
    for my $y (keys(%{ $h2{$x} })) { 
     push @{ $h1{$x}{$y} }, @{ $h2{$x}{$y} }; 
    } 
} 
+0

No funciona: 'No se puede usar un valor indefinido como referencia de ARRAY en la línea XX' – Zaid

+0

@Zaid, no obtengo ese error, aunque falta un signo de dólar. Fijo. Tuve que salir corriendo sin realizar pruebas antes, pero la versión actual está probada. – ikegami

+0

El problema estaba de mi parte ... nombres de var re-etiquetados incorrectamente – Zaid

0
sub merge_hashes { 
    my ($h1, $h2) = @_; 
    foreach my $key (keys %$h2) { 
     if (!exists $h1->{$key} || ref($h1->{$key}) ne 'HASH' || ref($h2->{$key}) ne 'HASH') { 

      $h1->{$key} = $h2->{$key}; 
     } 
     else { 
      merge_hashes($h1->{$key}, $h2->{$key}); 
     } 
    } 
} 

merge_hashes(\%hash1, \%hash2); 
0

Para los datos de muestra proporcionados, lo siguiente sería realizar la que la fusión describen:

my %merged = map { 
       $_ => { 
         %{$a{$_} // {}}, 
         %{$b{$_} // {}} 
        } 
      } (keys %a, keys %b); 

prueba:

use strict; 
use warnings; 
use Data::Dump 'dd'; 

my %a = (
abc => { 
     123 => [ 
      'xx', 
      'yy', 
      'zy' 
     ], 
     456 => [ 
      'ab', 
      'cd', 
      'ef' 
     ] 
    } 
); 
my %b = (
def => { 
     659 => [ 
      'wx', 
      'yg', 
      'kl' 
     ], 
     456 => [ 
      'as', 
      'sd', 
      'df' 
     ] 
    }, 
    abc => { 
     987 => [ 
      'lk', 
      'dm', 
      'sd' 
     ] 
    } 
); 

my %merged = map { 
        $_ => { 
          %{$a{$_} // {}}, 
          %{$b{$_} // {}} 
         } 
       } (keys %a, keys %b); 

dd \%merged; 
# { 
# abc => { 
#   123 => ["xx", "yy", "zy"], 
#   456 => ["ab", "cd", "ef"], 
#   987 => ["lk", "dm", "sd"], 
#   }, 
# def => { 456 => ["as", "sd", "df"], 659 => ["wx", "yg", "kl"] }, 
# }