Як я можу поєднати хеші в Perl?


95

Який найкращий спосіб поєднати обидва хеші в% hash1? Я завжди знаю, що% hash2 та% hash1 завжди мають унікальні ключі. Я б також віддав перевагу одному рядку коду, якщо це можливо.

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

Відповіді:


168

Швидка відповідь (TL; DR)

    % hash1 = (% hash1,% hash2)

    ## інакше ...

    @ hash1 {ключі% hash2} = значення% hash2;

    ## або з посиланнями ...

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

Огляд

  • Контекст: Perl 5.x
  • Проблема: Користувач бажає об’єднати два хеші 1 в одну змінну

Рішення

  • використовувати синтаксис вище для простих змінних
  • використовувати Hash :: Merge для складних вкладених змінних

Підводні камені

Дивитися також


Виноски

1 * (він же асоціативний масив , він же словник )


2
Так, якщо немає зіткнень ключів, @ hash1 {ключі% hash2} = значення% hash2; це найшвидший і найкоротший шлях, AFAIK.
kixx

46
чому ви не можете просто зробити%hash1 = (%hash1, %hash2)
user102008

1
Здається, це працює і з посиланнями: $ hash_ref1 = ($ hash_ref1, $ hash_ref2);
лепе

2
Це буде встановлено $hash_ref1на $hash_ref2, що не зрощування. Ви хочете $hash_ref1 = { %$hash_ref1, %$hash_ref2 };, я відредагую відповідь.
M Somerville

38

Перевірте perlfaq4: Як об’єднати два хеші . У документації Perl вже є багато корисної інформації, і ви можете отримати її відразу, а не чекати, поки хтось інший відповість на неї. :)


Перш ніж вирішити об’єднати два хеші, вам слід вирішити, що робити, якщо обидва хеші містять однакові ключі і якщо ви хочете залишити вихідні хеші такими, якими вони були.

Якщо ви хочете зберегти оригінальні хеші, скопіюйте один хеш (% hash1) у новий хеш (% new_hash), а потім додайте ключі від іншого хешу (% hash2 до нового хешу. Перевірка, що ключ уже існує в% new_hash дає можливість вирішити, що робити з дублікатами:

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

Якщо ви не хочете створювати новий хеш, ви все одно можете скористатися цією технологією циклу; просто змініть% new_hash на% 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};
        }
    }

Якщо вам байдуже, що один хеш перезаписує ключі та значення з іншого, ви можете просто використовувати хеш-фрагмент, щоб додати один хеш до іншого. У цьому випадку значення з% hash2 замінюють значення з% hash1, коли вони мають спільні ключі:

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

приємно посилатись на perlfaq та інші ресурси в іншому питанні
Кріс

14

Це давнє запитання, але воно з’являється високо в моєму пошуковому запиті Google щодо “хешів злиття perl” - і в ньому не згадується дуже корисний модуль CPAN Hash :: Merge


відповідь з найбільшим рейтингом оновлена, щоб включити це.
dreftymac

6

Для хеш-посилань. Вам слід використовувати фігурні дужки, як показано нижче:

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

і не запропонована відповідь вище з використанням дужок:

$hash_ref1 = ($hash_ref1, $hash_ref2);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.