ฉันจะรวมแฮชใน Perl ได้อย่างไร?


95

วิธีใดดีที่สุดในการรวมแฮชทั้งสองเป็น% hash1 ฉันรู้เสมอว่า% hash2 และ% hash1 มีคีย์ที่ไม่ซ้ำกันเสมอ ฉันต้องการโค้ดบรรทัดเดียวถ้าเป็นไปได้

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

คำตอบ:


169

คำตอบด่วน (TL; DR)

    % hash1 = (% hash1,% hash2)

    ## หรืออื่น ๆ ...

    @ hash1 {คีย์% hash2} = ค่า% hash2;

    ## หรือมีแหล่งอ้างอิง ...

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

ภาพรวม

  • บริบท: Perl 5.x
  • ปัญหา:ผู้ใช้ต้องการรวมสองแฮช1เป็นตัวแปรเดียว

วิธีการแก้

  • ใช้ไวยากรณ์ด้านบนสำหรับตัวแปรง่ายๆ
  • ใช้ Hash :: Merge สำหรับตัวแปรซ้อนที่ซับซ้อน

หลุมพราง

ดูสิ่งนี้ด้วย


เชิงอรรถ

1 * (aka Associative-array , aka dictionary )


2
ใช่ถ้าไม่มีการชนกันของคีย์ @ hash1 {keys% hash2} = values% hash2; เป็นวิธีที่เร็วและสั้นที่สุด AFAIK
kixx

47
ทำไมคุณทำไม่ได้%hash1 = (%hash1, %hash2)
user102008

1
ดูเหมือนว่าจะใช้งานได้กับการอ้างอิงเช่นกัน: $ hash_ref1 = ($ hash_ref1, $ hash_ref2);
lepe

2
ที่จะตั้งค่า$hash_ref1เป็น$hash_ref2ไม่มีการรวม คุณต้องการ$hash_ref1 = { %$hash_ref1, %$hash_ref2 };ฉันจะแก้ไขคำตอบ
M Somerville

39

ตรวจสอบperlfaq4: ฉันจะรวมสองแฮชได้อย่างไร มีข้อมูลที่ดีมากมายอยู่ในเอกสาร Perl แล้วและคุณสามารถรับได้ทันทีแทนที่จะรอให้คนอื่นตอบ :)


ก่อนที่คุณจะตัดสินใจรวมสองแฮชคุณต้องตัดสินใจว่าจะทำอย่างไรหากแฮชทั้งสองมีคีย์ที่เหมือนกันและถ้าคุณต้องการออกจากแฮชดั้งเดิมเหมือนเดิม

หากคุณต้องการรักษาแฮชดั้งเดิมให้คัดลอกแฮช (% แฮช 1) หนึ่งแฮชไปยังแฮชใหม่ (% new_hash) จากนั้นเพิ่มคีย์จากแฮชอื่น (% แฮช 2 ในแฮชใหม่ตรวจสอบว่าคีย์มีอยู่แล้วใน% 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 merge hashes' - แต่ก็ไม่ได้กล่าวถึงโมดูล CPAN ที่มีประโยชน์มากHash :: Merge


คำตอบที่ได้รับการโหวตสูงสุดได้รับการอัปเดตเพื่อรวมไว้ด้วย
dreftymac

6

สำหรับการอ้างอิงแฮช คุณควรใช้วงเล็บปีกกาดังต่อไปนี้:

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

และไม่ได้คำตอบที่แนะนำข้างต้นใช้วงเล็บ:

$hash_ref1 = ($hash_ref1, $hash_ref2);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.