¿Cómo puedo combinar hashes en Perl?

95

¿Cuál es la mejor manera de combinar ambos hash en% hash1? Siempre supe que% hash2 y% hash1 siempre tienen claves únicas. También preferiría una sola línea de código si es posible.

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

Respuestas:

168

Respuesta rápida (TL; DR)

    % hash1 = (% hash1,% hash2)

    ## si no ...

    @ hash1 {claves% hash2} = valores% hash2;

    ## o con referencias ...

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

Visión general

  • Contexto: Perl 5.x
  • Problema: el usuario desea fusionar dos hashes 1 en una sola variable

Solución

  • use la sintaxis anterior para variables simples
  • use Hash :: Merge para variables anidadas complejas

Trampas

Ver también


Notas al pie

1 * (también conocido como matriz asociativa , también conocido como diccionario )

dreftymac
fuente
2
Sí, si no hay colisiones de claves, @ hash1 {claves% hash2} = valores% hash2; es el camino más rápido y corto, AFAIK.
kixx
46
¿Por qué no puedes hacerlo%hash1 = (%hash1, %hash2)
user102008
1
Parece funcionar también con referencias: $ hash_ref1 = ($ hash_ref1, $ hash_ref2);
lepe
2
Eso se establecerá $hash_ref1en $hash_ref2, sin fusión. Si quieres $hash_ref1 = { %$hash_ref1, %$hash_ref2 };, editaré la respuesta.
M Somerville
38

Echa un vistazo a perlfaq4: ¿Cómo fusiono dos hashes ? Ya hay mucha información buena en la documentación de Perl y puede tenerla de inmediato en lugar de esperar a que otra persona la conteste. :)


Antes de decidir fusionar dos hashes, tienes que decidir qué hacer si ambos hashes contienen claves iguales y si quieres dejar los hashes originales como estaban.

Si desea conservar los hash originales, copie un hash (% hash1) en un nuevo hash (% new_hash), luego agregue las claves del otro hash (% hash2 al nuevo hash. Verificando que la clave ya existe en% new_hash te da la oportunidad de decidir qué hacer con los duplicados:

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 no desea crear un nuevo hash, aún puede utilizar esta técnica de bucle; simplemente cambie% new_hash a% 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 no le importa que un hash sobrescriba las claves y los valores del otro, puede usar un trozo de hash para agregar un hash a otro. En este caso, los valores de% hash2 reemplazan los valores de% hash1 cuando tienen claves en común:

@hash1{ keys %hash2 } = values %hash2;
Brian D Foy
fuente
agradable vincular a perlfaq y otros recursos en otra pregunta
Chris
14

Esta es una pregunta antigua, pero aparece en un lugar destacado en mi búsqueda de Google de 'perl merge hashes' y, sin embargo, no menciona el muy útil módulo CPAN Hash :: Merge

LeeGee
fuente
la respuesta más votada se ha actualizado para incluir esto.
dreftymac
6

Para referencias hash. Debes usar llaves como las siguientes:

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

y no la respuesta sugerida arriba usando paréntesis:

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