2012-09-24 3 views
5

dies ist eine Müllkippe meiner Hashes:% hash1Hash merge/Verkettung

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

und die zweite:% hash2

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

Jetzt habe ich diese beiden Hashes in einem neuen Hash zusammenführen möchten , aber wenn ein Schlüssel dupliziert wird (hier 'abc'), sollten die Werte angehängt, nicht ersetzt werden, daher sollten die Schlüssel eindeutig bleiben und alle Werte sollten ebenfalls beibehalten werden. Wie kann das in Perl gemacht werden? Die Ausgabe sollte wie folgt sein:

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

Können Sie mir ein Beispiel einer gemischten Daten geben Struktur, z zwischen '% a = (key1 => {key2 => [1]})' und '% b = (key1 => {key2 => [1]})'? Ich weiß nicht, welchen Weg ich nehmen soll, wenn ich nicht weiß, wohin ich gehe. – amon

+0

Ich habe die Hauptfrage mit der notwendigen Ausgabe bearbeitet, Danke für die Hilfe !! –

Antwort

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

Funktioniert nicht: 'Kann keinen undefinierten Wert als ARRAY-Referenz in Zeile XX' – Zaid

+0

@Zaid verwenden, bekomme ich diesen Fehler nicht, obwohl ein Dollarzeichen fehlt. Fest. Ich musste früher ohne Tests ausstürzen, aber die aktuelle Version wird getestet. – ikegami

+0

Das Problem war auf meiner Seite ... falsch beschriftet Var-Namen – 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

Für die Beispieldaten zur Verfügung gestellt, beschreiben die folgenden würde führen Sie die Zusammenführung:

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