user3098583
user3098583

Reputation: 31

Perl compare two hashes based on keys and retrieve values missing in either

Is there a module or best way to compare 2 hashes based on keys and retrieve and print values missing in 1st and 2nd hash?

I have two hashes which describe a particular configuration.
I want to compare two historical statuses of the configuration. In particular I am interested to know which key has been deleted and which key has been added. There is no need to know where the key has been edited (i.e., this does not happen).

Example:

Hash 1 keys:
aaa
bbb
ccc
ddd

Hash 2 keys:
aaa
xxx
bbb
ccc
yyy

The result should be something like:

xxx added
ddd deleted
yyy added

Any idea?

Upvotes: 3

Views: 6130

Answers (4)

Hynek -Pichi- Vychodil
Hynek -Pichi- Vychodil

Reputation: 26121

sub compare {
  my ($a, $b) = @_;
  [grep !exists $b->{$_}, keys %$a], [grep !exists $a->{$_}, keys %$b];
}

my @keys1 = qw(aaa bbb ccc ddd);
my @keys2 = qw(aaa xxx bbb ccc yyy);
my (%hash1, %hash2);
@hash1{@keys1}=();
@hash2{@keys2}=();
my ($deleted, $added) = compare(\%hash1, \%hash2);
print "Added: @$added, Deleted: @$deleted\n";

Upvotes: 2

Kenosis
Kenosis

Reputation: 6204

You can use List::Compare for this task:

use strict;
use warnings;
use List::Compare;

my %hash1 = map { $_ => undef } qw/aaa bbb ccc ddd/;
my %hash2 = map { $_ => undef } qw/aaa xxx bbb ccc yyy/;

my $lc = List::Compare->new( [ keys %hash1 ], [ keys %hash2 ] );

my @hash1Only = $lc->get_Lonly;
my @hash2Only = $lc->get_Ronly;

print "Added: @hash2Only\nDeleted: @hash1Only\n";

Output:

Added: xxx yyy
Deleted: ddd

Hope this helps!

Upvotes: 2

fugu
fugu

Reputation: 6578

use warnings;
use strict; 

my @array1 = qw (aaa bbb ccc ddd);
my @array2 = qw(aaa xxx bbb ccc yyy);
my (%hash1, %hash2);

@hash1{@array1} = 1;
@hash2{@array2} = 1;

foreach (keys %hash2){
    print "added $_\n" unless exists $hash1{$_};
}

foreach (keys %hash1){
    print "removed $_\n" unless exists $hash2{$_}; 
}

prints:

added xxx
added yyy
removed ddd

Upvotes: 0

DeVadder
DeVadder

Reputation: 1404

Iterate through all keys of hash 1. For each check wether it exists in hash 2. If not, it has been deleted. If it does, delete the key form hash 2. Once done, all the remaining keys in hash 2 are the ones that have been added.

edit: I assume you know how to write code in Perl and just needed an idea. If the answer sounds strange, look the words written like this up in Perldoc.

Upvotes: 0

Related Questions