Jak mogę łączyć hasze w Perlu?

Jaki jest najlepszy sposób na połączenie obu hashów w % hash1? Zawsze Wiem, że %hash2 i %hash1 zawsze mają unikalne klucze. Wolałbym również pojedynczą linię kodu, jeśli to możliwe.

$hash1{'1'} = 'red';
$hash1{'2'} = 'blue';
$hash2{'3'} = 'green';
$hash2{'4'} = 'yellow';
Author: dreftymac, 2008-12-08

4 answers

Szybka Odpowiedź (TL;DR)


    %hash1 = (%hash1, %hash2)

    ## or else ...

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

    ## or with references ...

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

Przegląd

  • Context: Perl 5.x
  • Problem: użytkownik chce połączyć dwa hasze1 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

  • Co zrobić, gdy oba skróty zawierają jeden lub więcej zduplikowanych kluczy
    • czy para klucz-wartość z pusta wartość Czy kiedykolwiek nadpisałeś parę klucz-wartość niepustą wartością?
    • co składa się na wartość pustą vs niepustą? (np. undef, empty string, false, falsy ...)
    • (Uwaga: pierwotne pytanie wyklucza ten scenariusz, ale jest to ważne do rozważenia)

Zobacz też


Przypisy

1 * (aka asocjacyjny-array , aka słownik )

 150
Author: dreftymac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-13 09:21:52

Zobacz perlfaq4: jak połączyć dwa hasze . Istnieje wiele dobrych informacji już w dokumentacji Perla i możesz je mieć od razu, zamiast czekać, aż ktoś inny na nie odpowie. :)


Zanim zdecydujesz się połączyć dwa skróty, musisz zdecydować, co zrobić, jeśli oba skróty zawierają klucze, które są takie same i jeśli chcesz zostawić oryginalne skróty takie, jakie były.

Jeśli chcesz zachować oryginalny hash, skopiuj jeden hash (%hash1) do nowego hash (%new_hash), następnie dodaj klucze z innego hasha (%hash2 do nowego hasha. Sprawdzenie, czy klucz już istnieje w %new_hash daje Ci szansę na podjęcie decyzji, 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 hasha, 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 hash nadpisuje klucze i wartości od drugiego, możesz użyć plasterka skrótu, aby dodać jeden hash do drugiego. W tym przypadku, wartości z % hash2 zastępują wartości z % hash1, gdy mają wspólne klucze:

@hash1{ keys %hash2 } = values %hash2;
 37
Author: brian d foy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-18 10:48:08

To stare pytanie, ale pojawia się wysoko w mojej wyszukiwarce Google dla 'Perl merge hashes' - a jednak nie wspomina o bardzo pomocnym module CPAN Hash:: Merge

 13
Author: LeeGee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-03 13:13:16

Dla odniesień hashowych. Powinieneś używać kręconych szelek, takich jak:

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

I Nie sugerowana powyżej odpowiedź za pomocą nawiasu:

$hash_ref1 = ($hash_ref1, $hash_ref2);
 4
Author: JeanieJ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-07 18:40:27