Comment puis-je combiner des hachages en Perl?

95

Quelle est la meilleure façon de combiner les deux hachages en% hash1? Je sais toujours que% hash2 et% hash1 ont toujours des clés uniques. Je préférerais également une seule ligne de code si possible.

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

Réponses:

168

Réponse rapide (TL; DR)

    % hash1 = (% hash1,% hash2)

    ## ou sinon ...

    @ hash1 {clés% hash2} = valeurs% hash2;

    ## ou avec des références ...

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

Aperçu

  • Contexte: Perl 5.x
  • Problème: l'utilisateur souhaite fusionner deux hachages 1 en une seule variable

Solution

  • utilisez la syntaxe ci-dessus pour des variables simples
  • utilisez Hash :: Merge pour les variables imbriquées complexes

Pièges

Voir également


Notes de bas de page

1 * (aka associative-array , aka dictionnaire )

dreftymac
la source
2
Oui, s'il n'y a pas de collision de clés, @ hash1 {keys% hash2} = values% hash2; est le moyen le plus rapide et le plus court, AFAIK.
kixx
46
pourquoi ne pouvez-vous pas simplement faire%hash1 = (%hash1, %hash2)
user102008
1
Il semble également fonctionner avec des références: $ hash_ref1 = ($ hash_ref1, $ hash_ref2);
lepe
2
Cela mis $hash_ref1à $hash_ref2, sans fusion. Vous voulez $hash_ref1 = { %$hash_ref1, %$hash_ref2 };, je modifierai la réponse.
M Somerville
38

Découvrez perlfaq4: Comment fusionner deux hachages . Il y a déjà beaucoup de bonnes informations dans la documentation Perl et vous pouvez les avoir tout de suite plutôt que d'attendre que quelqu'un d'autre y réponde. :)


Avant de décider de fusionner deux hachages, vous devez décider quoi faire si les deux hachages contiennent des clés identiques et si vous souhaitez laisser les hachages d'origine tels qu'ils étaient.

Si vous souhaitez conserver les hachages d'origine, copiez un hachage (% hash1) dans un nouveau hachage (% new_hash), puis ajoutez les clés de l'autre hachage (% hash2 au nouveau hachage. Vérification que la clé existe déjà dans% new_hash vous donne une chance de décider quoi faire avec les doublons:

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};
        }
    }

Si vous ne souhaitez pas créer de nouveau hachage, vous pouvez toujours utiliser cette technique de bouclage; changez simplement le% new_hash en% 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};
        }
    }

Si vous ne vous souciez pas qu'un hachage écrase les clés et les valeurs de l'autre, vous pouvez simplement utiliser une tranche de hachage pour ajouter un hachage à un autre. Dans ce cas, les valeurs de% hash2 remplacent les valeurs de% hash1 lorsqu'elles ont des clés en commun:

@hash1{ keys %hash2 } = values %hash2;
brian d foy
la source
agréable de créer un lien vers perlfaq, et d'autres ressources dans une autre question
Chris
14

C'est une vieille question, mais qui ressort en haut de ma recherche Google pour 'perl merge hashes' - et pourtant elle ne mentionne pas le très utile module CPAN Hash :: Merge

LeeGee
la source
la réponse la plus votée a été mise à jour pour inclure cela.
dreftymac
6

Pour les références de hachage. Vous devez utiliser des accolades comme celles-ci:

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

et non la réponse suggérée ci-dessus en utilisant des parenthèses:

$hash_ref1 = ($hash_ref1, $hash_ref2);
JeanieJ
la source