Jak mogę łączyć skróty w Perlu?


95

Jaki jest najlepszy sposób połączenia obu skrótów w% hash1? Zawsze wiem, że% hash2 i% hash1 zawsze mają unikalne klucze. Wolałbym również, jeśli to możliwe, jeden wiersz kodu.

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

Odpowiedzi:


168

Szybka odpowiedź (TL; DR)

    % hash1 = (% hash1,% hash2)

    ## albo ...

    @ hash1 {klucze% hash2} = wartości% hash2;

    ## lub z referencjami ...

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

Przegląd

  • Kontekst: Perl 5.x
  • Problem: użytkownik chce połączyć dwa skróty 1 w jedną zmienną

Rozwiązanie

  • użyj powyższej składni dla prostych zmiennych
  • użyj Hash :: Merge dla złożonych zagnieżdżonych zmiennych

Pułapki

Zobacz też


Przypisy

1 * (inaczej tablica asocjacyjna , inaczej słownik )


2
Tak, jeśli nie ma kolizji kluczy, @ hash1 {klucze% hash2} = wartości% hash2; to najszybsza i najkrótsza droga, AFAIK.
kixx

46
dlaczego nie możesz po prostu zrobić%hash1 = (%hash1, %hash2)
user102008

1
Wygląda na to, że działa również z referencjami: $ hash_ref1 = ($ hash_ref1, $ hash_ref2);
lepe

2
To będzie ustawione $hash_ref1na $hash_ref2, bez łączenia. Chcesz $hash_ref1 = { %$hash_ref1, %$hash_ref2 };, poprawię odpowiedź.
M Somerville,

38

Sprawdź perlfaq4: Jak połączyć dwa skróty . W dokumentacji Perla jest już wiele dobrych informacji i możesz je mieć od razu, zamiast czekać, aż ktoś inny odpowie. :)


Zanim zdecydujesz się scalić dwa skróty, musisz zdecydować, co zrobić, jeśli oba skróty zawierają takie same klucze i chcesz pozostawić oryginalne skróty bez zmian.

Jeśli chcesz zachować oryginalne skróty, skopiuj jeden skrót (% hash1) do nowego skrótu (% new_hash), a następnie dodaj klucze z drugiego skrótu (% hash2 do nowego skrótu. Sprawdzanie, czy klucz już istnieje w% new_hash) daje szansę zdecydować, co zrobić z duplikatami:

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

Jeśli nie chcesz tworzyć nowego skrótu, nadal możesz użyć tej techniki zapętlania; po prostu zmień% new_hash na% 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};
        }
    }

Jeśli nie obchodzi Cię, że jeden skrót zastępuje klucze i wartości drugiego, możesz po prostu użyć wycinka skrótu, aby dodać jeden skrót do drugiego. W tym przypadku wartości z% hash2 zastępują wartości z% hash1, jeśli mają wspólne klucze:

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

fajny link do perlfaq i innych zasobów w innych kwestiach
Chris

14

To jest stare pytanie, ale pojawia się wysoko w moim wyszukiwaniu w Google pod kątem „perl merge hashes” - a mimo to nie wspomina o bardzo pomocnym module CPAN Hash :: Merge


odpowiedź z największą liczbą głosów została zaktualizowana, aby to uwzględnić.
dreftymac

6

W przypadku odwołań do skrótów Powinieneś używać nawiasów klamrowych, takich jak:

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

a nie sugerowaną powyżej odpowiedź w nawiasach:

$hash_ref1 = ($hash_ref1, $hash_ref2);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.