¿Cómo puedo combinar hashes en Perl?
¿Cuál es la mejor manera de combinar ambos hashes en %hash1? Siempre sé 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';
4 answers
Respuesta rápida (TL; DR)
%hash1 = (%hash1, %hash2) ## or else ... @hash1{keys %hash2} = values %hash2; ## or with references ... $hash_ref1 = { %$hash_ref1, %$hash_ref2 };
Descripción general
- Contexto: Perl 5.x
- Problema: El usuario desea combinar dos hashes1 en una sola variable
Solución
- utilice la sintaxis anterior para variables simples
- use Hash:: Merge para variables anidadas complejas
Trampas
- Qué hacer cuando ambos hashes contienen una o más claves duplicadas
- Si un par clave-valor con un valor vacío nunca sobrescribir un par clave-valor con un valor no vacío?
- ¿Qué constituye un valor vacío vs no vacío en primer lugar? (eg.
undef
, cadena vacía,false
, falsy ...) - (Nota: la pregunta original descarta este escenario, pero es importante considerarlo)
Véase también
- Mensaje de PM sobre la fusión de hashes
- PM Categorical Q & A hash union
- Perl Cookbook 5.10. Fusionar Hashes
- websearch: / / perlfaq "combinar dos hashes"
- websearch: / / hash de fusión de perl
- https://metacpan.org/pod/Hash::Merge
Notas al pie
1 * (aka matriz asociativa , aka diccionario )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-13 09:21:52
Echa un vistazo perlfaq4: Cómo combinar 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 alguien más la responda. :)
Antes de decidir fusionar dos hashes, debe decidir qué hacer si ambos hashes contienen claves que son las mismas y si desea dejar los hashes originales como estaban.
Si desea conservar los hashes originales, copie un hash (%hash1) a un nuevo hash (%new_hash), luego agregue las claves del otro hash (%hash2 al nuevo hash. Comprobar 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, todavía puede usar 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, podría usar un hash slice 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;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-18 10:48:08
Esta es una vieja pregunta, pero sale muy alto en mi búsqueda de Google para 'perl merge hashes' - y sin embargo no menciona el muy útil módulo CPAN Hash:: Merge
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-03 13:13:16
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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-07 18:40:27