2012-09-24 9 views
5

jest to zrzut z moich skrótów:% hash1Hash seryjnej/konkatenacji

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

a drugi:% hash2

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

Teraz chcę połączyć te dwa hashe w nowym hash , ale jeśli klucz jest duplikowany (tutaj "abc"), wartości powinny być dołączane, a nie zastępowane, więc klucze powinny pozostać niepowtarzalne, a wszystkie wartości powinny również zostać zachowane. Jak to zrobić w Perlu? wyjście jest następująca:

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

Czy możesz dać mi przykład scalonych danych struktura, np między '% a = (key1 => {key2 => [1]})' i '% b = (key1 => {key2 => [1]})'? Nie wiem, którą drogę wybrać, gdy nie wiem, dokąd zmierzam. – amon

+0

Edytowałem główne pytanie z niezbędnymi wynikami, dzięki za pomoc !! –

Odpowiedz

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

Nie działa: 'Nie można użyć niezdefiniowanej wartości jako ARRAY reference at - line XX'' – Zaid

+0

@Zaid, nie dostaję tego błędu, chociaż brakuje znaku dolara. Naprawiony. Musiałem wcześniej wypaść bez testowania, ale obecna wersja jest testowana. – ikegami

+0

Problem był po mojej stronie ... oznaczone ponownie nazwy var błędnie – 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

Do przykładowych danych dostarczonych następujące byłoby wykonać połączenia można opisać:

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

Test:

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"] }, 
# }