Come posso combinare gli hash in Perl?


95

Qual è il modo migliore per combinare entrambi gli hash in% hash1? So sempre che% hash2 e% hash1 hanno sempre chiavi univoche. Preferirei anche una singola riga di codice, se possibile.

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

Risposte:


168

Risposta rapida (TL; DR)

    % hash1 = (% hash1,% hash2)

    ## o altro ...

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

    ## o con riferimenti ...

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

Panoramica

  • Contesto: Perl 5.x
  • Problema: l'utente desidera unire due hash 1 in un'unica variabile

Soluzione

  • utilizzare la sintassi precedente per variabili semplici
  • usa Hash :: Merge per variabili annidate complesse

Insidie

Guarda anche


Note a piè di pagina

1 * (aka array associativo , aka dizionario )


2
Sì, se non ci sono conflitti di chiavi, @ hash1 {keys% hash2} = values% hash2; è il modo più veloce e più breve, AFAIK.
kixx

46
perché non puoi semplicemente farlo%hash1 = (%hash1, %hash2)
user102008

1
Sembra funzionare anche con i riferimenti: $ hash_ref1 = ($ hash_ref1, $ hash_ref2);
lepe

2
Che fisserà $hash_ref1a $hash_ref2, no fusione. Se vuoi $hash_ref1 = { %$hash_ref1, %$hash_ref2 };, modifico la risposta.
M Somerville

38

Dai un'occhiata a perlfaq4: come unisco due hash . Ci sono già molte buone informazioni nella documentazione di Perl e puoi averle subito piuttosto che aspettare che qualcun altro risponda. :)


Prima di decidere di unire due hash, devi decidere cosa fare se entrambi gli hash contengono chiavi uguali e se vuoi lasciare gli hash originali come erano.

Se vuoi conservare gli hash originali, copia un hash (% hash1) in un nuovo hash (% new_hash), quindi aggiungi le chiavi dell'altro hash (% hash2 al nuovo hash. Controllando che la chiave esista già in% new_hash ti dà la possibilità di decidere cosa fare con i duplicati:

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 non vuoi creare un nuovo hash, puoi comunque usare questa tecnica di loop; basta cambiare% 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};
        }
    }

Se non ti interessa che un hash sovrascrive chiavi e valori dall'altro, puoi semplicemente usare una fetta di hash per aggiungere un hash a un altro. In questo caso, i valori di% hash2 sostituiscono i valori di% hash1 quando hanno chiavi in ​​comune:

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

bello il collegamento a perlfaq e altre risorse in altre domande
Chris

14

Questa è una vecchia domanda, ma emerge in cima alla mia ricerca su Google per 'perl merge hash' - e tuttavia non menziona l'utilissimo modulo CPAN Hash :: Merge


la risposta più votata è stata aggiornata per includerla.
dreftymac

6

Per riferimenti hash. Dovresti usare le parentesi graffe come le seguenti:

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

e non la risposta suggerita sopra usando le parentesi:

$hash_ref1 = ($hash_ref1, $hash_ref2);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.