How can I combine hashes in Perl?

PerlDictionaryHashMerge

Perl Problem Overview


What is the best way to combine both hashes into %hash1? I always know that %hash2 and %hash1 always have unique keys. I would also prefer a single line of code if possible.

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

Perl Solutions


Solution 1 - Perl

Quick Answer (TL;DR)

%hash1 = (%hash1, %hash2)

## or else ...

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

## or with references ...

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

Overview

  • Context: Perl 5.x
  • Problem: The user wishes to merge two hashes1 into a single variable

Solution

  • use the syntax above for simple variables
  • use Hash::Merge for complex nested variables

Pitfalls

See also


Footnotes

1 * (aka associative-array, aka dictionary)

Solution 2 - Perl

Check out perlfaq4: How do I merge two hashes. There is a lot of good information already in the Perl documentation and you can have it right away rather than waiting for someone else to answer it. :)


Before you decide to merge two hashes, you have to decide what to do if both hashes contain keys that are the same and if you want to leave the original hashes as they were.

If you want to preserve the original hashes, copy one hash (%hash1) to a new hash (%new_hash), then add the keys from the other hash (%hash2 to the new hash. Checking that the key already exists in %new_hash gives you a chance to decide what to do with the duplicates:

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

If you don't want to create a new hash, you can still use this looping technique; just change the %new_hash to %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};
		}
	}

If you don't care that one hash overwrites keys and values from the other, you could just use a hash slice to add one hash to another. In this case, values from %hash2 replace values from %hash1 when they have keys in common:

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

Solution 3 - Perl

This is an old question, but comes out high in my Google search for 'perl merge hashes' - and yet it does not mention the very helpful CPAN module Hash::Merge

Solution 4 - Perl

For hash references. You should use curly braces like the following:

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

and not the suggested answer above using parenthesis:

$hash_ref1 = ($hash_ref1, $hash_ref2);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmleykampView Question on Stackoverflow
Solution 1 - PerldreftymacView Answer on Stackoverflow
Solution 2 - Perlbrian d foyView Answer on Stackoverflow
Solution 3 - PerlLee GoddardView Answer on Stackoverflow
Solution 4 - PerlJeanieJView Answer on Stackoverflow