Wie kann ich Hashes in Perl kombinieren?

95

Was ist der beste Weg, um beide Hashes zu% hash1 zu kombinieren? Ich weiß immer, dass% hash2 und% hash1 immer eindeutige Schlüssel haben. Ich würde auch eine einzelne Codezeile bevorzugen, wenn möglich.

$hash1{'1'} = 'red';
$hash1{'2'} = 'blue';
$hash2{'3'} = 'green';
$hash2{'4'} = 'yellow';
mleykamp
quelle

Antworten:

167

Schnelle Antwort (TL; DR)

    % hash1 = (% hash1,% hash2)

    ## oder sonst ...

    @ hash1 {keys% hash2} = Werte% hash2;

    ## oder mit Referenzen ...

    $ hash_ref1 = {% $ hash_ref1,% $ hash_ref2};

Überblick

  • Kontext: Perl 5.x.
  • Problem: Der Benutzer möchte zwei Hashes 1 zu einer einzigen Variablen zusammenführen

Lösung

  • Verwenden Sie die obige Syntax für einfache Variablen
  • Verwenden Sie Hash :: Merge für komplexe verschachtelte Variablen

Tücken

Siehe auch


Fußnoten

1 * (aka assoziatives Array , aka Wörterbuch )

dreftymac
quelle
2
Ja, wenn keine Schlüsselkollisionen vorliegen, @ hash1 {keys% hash2} = Werte% hash2; ist der schnellste und kürzeste Weg, AFAIK.
Kixx
46
warum kannst du das nicht einfach machen%hash1 = (%hash1, %hash2)
user102008
1
Es scheint auch mit Referenzen zu funktionieren: $ hash_ref1 = ($ hash_ref1, $ hash_ref2);
Lepe
2
Das wird festgelegt $hash_ref1auf $hash_ref2, keine Verschmelzung. Sie wollen $hash_ref1 = { %$hash_ref1, %$hash_ref2 };, ich werde die Antwort bearbeiten.
M Somerville
38

Check out perlfaq4: Wie kann ich zwei Hashes verschmelzen . Die Perl-Dokumentation enthält bereits viele gute Informationen, die Sie sofort erhalten können, anstatt darauf zu warten, dass jemand anderes sie beantwortet. :) :)


Bevor Sie zwei Hashes zusammenführen, müssen Sie entscheiden, was zu tun ist, wenn beide Hashes dieselben Schlüssel enthalten und Sie die ursprünglichen Hashes unverändert lassen möchten.

Wenn Sie die ursprünglichen Hashes beibehalten möchten, kopieren Sie einen Hash (% hash1) in einen neuen Hash (% new_hash) und fügen Sie dann die Schlüssel aus dem anderen Hash (% hash2) in den neuen Hash ein. Überprüfen Sie, ob der Schlüssel bereits in% new_hash vorhanden ist gibt Ihnen die Möglichkeit zu entscheiden, was mit den Duplikaten geschehen soll:

my %new_hash = %hash1; # make a copy; leave %hash1 alone

foreach my $key2 ( keys %hash2 )
    {
    if( exists $new_hash{$key2} )
        {
        warn "Key [$key2] is in both hashes!";
        # handle the duplicate (perhaps only warning)
        ...
        next;
        }
    else
        {
        $new_hash{$key2} = $hash2{$key2};
        }
    }

Wenn Sie keinen neuen Hash erstellen möchten, können Sie diese Schleifentechnik weiterhin verwenden. Ändern Sie einfach% new_hash in% hash1.

foreach my $key2 ( keys %hash2 )
    {
    if( exists $hash1{$key2} )
        {
        warn "Key [$key2] is in both hashes!";
        # handle the duplicate (perhaps only warning)
        ...
        next;
        }
    else
        {
        $hash1{$key2} = $hash2{$key2};
        }
    }

Wenn es Ihnen egal ist, dass ein Hash Schlüssel und Werte des anderen überschreibt, können Sie einfach ein Hash-Slice verwenden, um einen Hash zu einem anderen hinzuzufügen. In diesem Fall ersetzen Werte aus% hash2 Werte aus% hash1, wenn sie Schlüssel gemeinsam haben:

@hash1{ keys %hash2 } = values %hash2;
brian d foy
quelle
Schön, auf Perlfaq und andere Ressourcen in anderen Fragen zu verlinken
Chris
14

Dies ist eine alte Frage, die jedoch in meiner Google-Suche nach "Perl-Merge-Hashes" ganz oben steht - und dennoch wird das sehr hilfreiche CPAN-Modul Hash :: Merge nicht erwähnt

LeeGee
quelle
Die Antwort mit der höchsten Bewertung wurde aktualisiert, um dies einzuschließen.
Dreftymac
6

Für Hash-Referenzen. Sie sollten geschweifte Klammern wie die folgenden verwenden:

$hash_ref1 = {%$hash_ref1, %$hash_ref2};

und nicht die oben vorgeschlagene Antwort in Klammern:

$hash_ref1 = ($hash_ref1, $hash_ref2);
JeanieJ
quelle