Karmaları Perl'de nasıl birleştirebilirim?


95

Her iki hash'ı% hash1 ile birleştirmenin en iyi yolu nedir? % Hash2 ve% hash1'in her zaman benzersiz anahtarlara sahip olduğunu her zaman bilirim. Mümkünse tek bir kod satırını da tercih ederim.

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

Yanıtlar:


168

Hızlı Cevap (TL; DR)

    % hash1 = (% hash1,% hash2)

    ## veya başka ...

    @ hash1 {anahtarlar% hash2} = değerler% hash2;

    ## veya referanslarla ...

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

Genel Bakış

  • Bağlam: Perl 5.x
  • Sorun: Kullanıcı, iki karma 1'i tek bir değişkene birleştirmek istiyor

Çözüm

  • basit değişkenler için yukarıdaki sözdizimini kullanın
  • karmaşık iç içe değişkenler için Hash :: Merge kullanın

Tuzaklar

Ayrıca bakınız


Dipnotlar

1 * (aka ilişkilendirilebilir dizi , aka sözlük )


2
Evet, anahtar çakışması yoksa, @ hash1 {anahtarlar% hash2} = değerler% hash2; en hızlı ve en kısa yol, AFAIK.
kixx

47
neden sadece yapamıyorsun%hash1 = (%hash1, %hash2)
user102008

1
Referanslarla da çalışıyor gibi görünüyor: $ hash_ref1 = ($ hash_ref1, $ hash_ref2);
lepe

2
Yani koyacaktır $hash_ref1için $hash_ref2, hiçbir birleşmesiyle. İsterseniz $hash_ref1 = { %$hash_ref1, %$hash_ref2 };cevabı düzenleyeceğim.
M Somerville

39

Perlfaq4'e göz atın: İki karmayı nasıl birleştiririm . Perl belgelerinde halihazırda pek çok iyi bilgi vardır ve bir başkasının cevaplamasını beklemek yerine hemen alabilirsiniz. :)


İki karmayı birleştirmeye karar vermeden önce, her iki karma da aynı anahtarlar içeriyorsa ve orijinal karmaları olduğu gibi bırakmak istiyorsanız ne yapmanız gerektiğine karar vermelisiniz.

Orijinal hash'leri korumak istiyorsanız, bir hash'i (% hash1) yeni bir hash'e (% new_hash) kopyalayın, ardından diğer hash'deki anahtarları (% hash2 yeni hash'e ekleyin. Anahtarın% new_hash içinde zaten mevcut olup olmadığı kontrol ediliyor) size kopyalarla ne yapacağınıza karar verme şansı verir:

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

Yeni bir karma oluşturmak istemiyorsanız, yine de bu döngü tekniğini kullanabilirsiniz; sadece% new_hash'i% hash1 olarak değiştirin.

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

Bir hash'in diğerinden anahtarların ve değerlerin üzerine yazması umurunuzda değilse, bir hash'i diğerine eklemek için bir hash dilimi kullanabilirsiniz. Bu durumda,% hash2'deki değerler, ortak anahtarlara sahip olduklarında% hash1'deki değerlerin yerini alır:

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

perlfaq'a ve başka bir sorudaki diğer kaynaklara bağlantı kurmak güzel
Chris

14

Bu eski bir soru, ancak Google aramamda 'perl merge hash'ları' için üst sıralarda çıkıyor - ve yine de çok yararlı CPAN modülü Hash :: Merge'den bahsetmiyor


en çok oy alan cevap bunu içerecek şekilde güncellenmiştir.
dreftymac

6

Karma referanslar için. Aşağıdaki gibi küme parantezi kullanmalısınız:

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

ve yukarıda parantez kullanılarak önerilen yanıt değil :

$hash_ref1 = ($hash_ref1, $hash_ref2);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.