Làm cách nào để kết hợp hàm băm trong Perl?


95

Cách tốt nhất để kết hợp cả hai hàm băm thành% hash1 là gì? Tôi luôn biết rằng% hash2 và% hash1 luôn có các khóa duy nhất. Tôi cũng muốn một dòng mã duy nhất nếu có thể.

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

Câu trả lời:


168

Trả lời nhanh (TL; DR)

    % hash1 = (% hash1,% hash2)

    ## hoặc cái gì đó khác ...

    @ hash1 {key% hash2} = giá trị% hash2;

    ## hoặc với các tham chiếu ...

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

Tổng quat

  • Bối cảnh: Perl 5.x
  • Vấn đề: Người dùng muốn hợp nhất hai hàm băm 1 thành một biến duy nhất

Giải pháp

  • sử dụng cú pháp trên cho các biến đơn giản
  • sử dụng Hash :: Merge cho các biến lồng nhau phức tạp

Cạm bẫy

Xem thêm


Chú thích

1 * (còn gọi là mảng kết hợp , còn gọi là từ điển )


2
Có, nếu không có xung đột chính, @ hash1 {key% hash2} = values% hash2; là con đường nhanh nhất và ngắn nhất, AFAIK.
kixx

46
tại sao có thể không chỉ cần làm%hash1 = (%hash1, %hash2)
user102008

1
Nó dường như cũng hoạt động với các tham chiếu: $ hash_ref1 = ($ hash_ref1, $ hash_ref2);
lepe

2
Điều đó sẽ được đặt $hash_ref1thành $hash_ref2, không hợp nhất. Bạn muốn $hash_ref1 = { %$hash_ref1, %$hash_ref2 };, tôi sẽ chỉnh sửa câu trả lời.
M Somerville

38

Kiểm tra perlfaq4: Làm cách nào để hợp nhất hai hàm băm . Có rất nhiều thông tin tốt đã có trong tài liệu Perl và bạn có thể có nó ngay lập tức thay vì đợi người khác trả lời. :)


Trước khi bạn quyết định hợp nhất hai hàm băm, bạn phải quyết định phải làm gì nếu cả hai hàm băm chứa các khóa giống nhau và nếu bạn muốn giữ nguyên các hàm băm ban đầu.

Nếu bạn muốn giữ nguyên các hàm băm ban đầu, hãy sao chép một hàm băm (% hash1) sang một hàm băm mới (% new_hash), sau đó thêm các khóa từ hàm băm khác (% hash2 vào hàm băm mới. Kiểm tra xem khóa đã tồn tại trong% new_hash chưa cho bạn cơ hội quyết định phải làm gì với các bản sao:

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

Nếu bạn không muốn tạo một băm mới, bạn vẫn có thể sử dụng kỹ thuật lặp này; chỉ cần thay đổi% new_hash thành% 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};
        }
    }

Nếu bạn không quan tâm đến việc một băm này ghi đè các khóa và giá trị từ băm kia, bạn có thể chỉ cần sử dụng một lát băm để thêm một băm này vào một băm khác. Trong trường hợp này, các giá trị từ% hash2 thay thế các giá trị từ% hash1 khi chúng có các khóa chung:

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

tốt đẹp để liên kết đến perlfaq, và các nguồn lực khác trong câu hỏi khác
Chris

14

Đây là một câu hỏi cũ, nhưng xuất hiện cao trong tìm kiếm Google của tôi về 'mã băm hợp nhất perl' - và nó không đề cập đến mô-đun CPAN rất hữu ích Hash :: Merge


câu trả lời được bình chọn nhiều nhất đã được cập nhật để bao gồm điều này.
dreftymac

6

Đối với tham chiếu băm. Bạn nên sử dụng dấu ngoặc nhọn như sau:

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

không phải câu trả lời được đề xuất ở trên bằng cách sử dụng dấu ngoặc đơn:

$hash_ref1 = ($hash_ref1, $hash_ref2);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.