Robie Nayak
Robie Nayak

Reputation: 827

Build a hash with values from two other hashes?

I have two hashes which have similar keys but different values.

I want to build a third hash with all the keys of the first hash and all the values of the second.

If the second hash doesn't have an element for any given key then the corresponding value for the resultant hash should be blank or undef.

For example, with these hashes

my %hash1 = (
  BLUE   => 30,
  GREEN  => 40,
  INDIGO => 12,
  ORANGE => 56,
  RED    => 45,
  VIOLET => 25,
  YELLOW => 10,
);

my %hash2 = (
  BLUE   => ["command1", "command2", "command3", "command4"],
  GREEN  => ["Windows", "Linux", "Unix", "Mac"],
  INDIGO => ["Air", "Earth", "Sky", "Water", "Fire"],
  RED    => ["physics", "chemistry", "biology"],
  YELLOW => ["Apple", "Orange"],
);

I want to produce this

my %hash3 = (
  BLUE   => ["command1", "command2", "command3", "command4"],
  GREEN  => ["Windows", "Linux", "Unix", "Mac"],
  INDIGO => ["Air", "Earth", "Sky", "Water", "Fire"],
  ORANGE => [],
  RED    => ["physics", "chemistry", "biology"],
  VIOLET => [],
  YELLOW => ["Apple", "Orange"],
);

The code I am trying is as follows but it throws an error. Can you please identify what I am missing?

foreach my $key (keys %hash1) {
  push @{$hash3{$key}} @{$hash2{$key}};
}

Upvotes: 1

Views: 104

Answers (3)

Robie Nayak
Robie Nayak

Reputation: 827

I just wrote the following piece of code and it worked.

foreach my $key (keys %hash1) {
    if (exists ($hash2{$key})) {
        push @{$hash3{$key}}, @{$hash2{$key}};
    }
    else {
         $hash3{$key} = [ ];
    }
}

Upvotes: 0

Borodin
Borodin

Reputation: 126722

All you need is

my %hash3 = map { $_ => $hash2{$_} } keys %hash1;

which takes the every key from %hash and pairs it with the corresponding value from %hash2 to form %hash3. Accessing non-existent elements in %hash2 will return undef without further code.

output

(
  BLUE   => ["command1", "command2", "command3", "command4"],
  GREEN  => ["Windows", "Linux", "Unix", "Mac"],
  INDIGO => ["Air", "Earth", "Sky", "Water", "Fire"],
  ORANGE => undef,
  RED    => ["physics", "chemistry", "biology"],
  VIOLET => undef,
  YELLOW => ["Apple", "Orange"],
)

Update

You asked for "blank or undef" for values of %hash3 where there is no value in %hash2, but your requested result shows empty anonymous arrays instead. To achieve this you just need to change the code to

my %hash3 = map { $_ => $hash2{$_} // [] } keys %hash1;

which gives this output

(
  BLUE   => ["command1", "command2", "command3", "command4"],
  GREEN  => ["Windows", "Linux", "Unix", "Mac"],
  INDIGO => ["Air", "Earth", "Sky", "Water", "Fire"],
  ORANGE => [],
  RED    => ["physics", "chemistry", "biology"],
  VIOLET => [],
  YELLOW => ["Apple", "Orange"],
)

Upvotes: 2

choroba
choroba

Reputation: 241918

A comma is missing between the arguments of push.

push @{$hash3{$key}}, @{$hash2{$key}};

Upvotes: 3

Related Questions