Como posso combinar hashes em Perl?

95

Qual é a melhor maneira de combinar os dois hashes em% hash1? Sempre soube que% hash2 e% hash1 sempre têm chaves exclusivas. Eu também preferiria uma única linha de código, se possível.

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

Respostas:

168

Resposta Rápida (TL; DR)

    % hash1 = (% hash1,% hash2)

    ## se não ...

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

    ## ou com referências ...

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

Visão geral

  • Contexto: Perl 5.x
  • Problema: O usuário deseja mesclar dois hashes 1 em uma única variável

Solução

  • use a sintaxe acima para variáveis ​​simples
  • use Hash :: Merge para variáveis ​​aninhadas complexas

Armadilhas

Veja também


Notas de rodapé

1 * (também conhecido como matriz associativa , também conhecido como dicionário )

dreftymac
fonte
2
Sim, se não houver colisões de chaves, @ hash1 {keys% hash2} = values% hash2; é o caminho mais rápido e curto, AFAIK.
kixx
46
por que você não pode simplesmente fazer%hash1 = (%hash1, %hash2)
user102008
1
Parece funcionar com referências também: $ hash_ref1 = ($ hash_ref1, $ hash_ref2);
lepe
2
Isso será definido $hash_ref1como $hash_ref2, sem fusão. Se quiser $hash_ref1 = { %$hash_ref1, %$hash_ref2 };, vou editar a resposta.
M Somerville
38

Confira perlfaq4: Como faço para mesclar dois hashes . Já existem muitas informações boas na documentação do Perl e você pode obtê-las imediatamente ao invés de esperar que alguém responda. :)


Antes de decidir mesclar dois hashes, você deve decidir o que fazer se ambos os hashes contiverem chaves iguais e se quiser deixar os hashes originais como estavam.

Se você quiser preservar os hashes originais, copie um hash (% hash1) para um novo hash (% new_hash) e adicione as chaves do outro hash (% hash2 para o novo hash. Verificando se a chave já existe em% new_hash dá a você a chance de decidir o que fazer com as duplicatas:

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

Se não quiser criar um novo hash, você ainda pode usar esta técnica de loop; apenas mude o% new_hash para% 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};
        }
    }

Se você não se importa que um hash substitua as chaves e valores do outro, você pode simplesmente usar uma fatia de hash para adicionar um hash a outro. Nesse caso, os valores de% hash2 substituem os valores de% hash1 quando têm chaves em comum:

@hash1{ keys %hash2 } = values %hash2;
brian d foy
fonte
bom link para perlfaq e outros recursos em outras questões
Chris
14

Esta é uma pergunta antiga, mas aparece em alta na minha pesquisa no Google por 'hashes de mesclagem de perl' - e ainda não menciona o módulo CPAN muito útil Hash :: Merge

LeeGee
fonte
a resposta mais votada foi atualizada para incluir isso.
dreftymac
6

Para referências de hash. Você deve usar colchetes como o seguinte:

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

e não a resposta sugerida acima usando parênteses:

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