in reply to Re^2: How best to compare hash values?
in thread How best to compare hash values?

But if your keys are just numbers, then the array index can be the number you need. Note that in my example, I used undef as a place holder for array elements that did not have an entry. Unless your indices are not even remotely sequential or you have non-integer indices, an array will be faster, take less memory and will apply a useful constraint on your keys.

If there is a possibility that your arrays or hashes do not have equivalent keys, it is considered best practice to test prior to processing those values. Modifying the previously posted codes:

Hashes:

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my %hash1 = ("1", "20", "2", "20", "4", "19", "5", "20", "6", "18", "7", "20"); my %hash2 = ("1", "19", "2", "20", "4", "16", "5", "19", "6", "20", "8", "20"); my %differences; for my $key ( sort {$a <=> $b} keys %hash1) { unless (defined $hash2{$key}) { print "$key is in \%hash1 but not \%hash2\n"; next; } $differences{$key} = $hash1{$key} - $hash2{$key}; print "$key ($hash1{$key} - $hash2{$key}) = $differences{$key}\n"; } print "\n", Dumper \%differences; __END__ 1 (20 - 19) = 1 2 (20 - 20) = 0 4 (19 - 16) = 3 5 (20 - 19) = 1 6 (18 - 20) = -2 7 is in %hash1 but not %hash2 $VAR1 = { '6' => -2, '4' => 3, '1' => 1, '2' => 0, '5' => 1 };

Arrays:

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @array1 = (undef,20,20,19,20,undef,18,20); my @array2 = (undef,19,20,16,19,undef,20,undef,20); my @differences; my $top = $#array1 > $#array2 ? $#array1 : $#array2; for my $i (1 .. $top) { if (defined $array1[$i] and not defined $array2[$i]) { print "$i is in \@array1 but not \@array2\n"; } if (not defined $array1[$i] and defined $array2[$i]) { print "$i is in \@array2 but not \@array1\n"; } next unless defined $array1[$i] and defined $array2[$i]; $differences[$i] = $array1[$i] - $array2[$i]; print "$i ($array1[$i] - $array2[$i]) = $differences[$i]\n"; } print "\n", Dumper \@differences; __END__ 1 (20 - 19) = 1 2 (20 - 20) = 0 3 (19 - 16) = 3 4 (20 - 19) = 1 6 (18 - 20) = -2 7 is in @array1 but not @array2 8 is in @array2 but not @array1 $VAR1 = [ undef, 1, 0, 3, 1, undef, -2 ];

Note that in the array case, I will not miss that the second set has a value that the first one is missing.

Replies are listed 'Best First'.
Re^4: How best to compare hash values?
by jimbass (Novice) on May 05, 2010 at 22:44 UTC

    Excellent, thanks!

    I'll redo my scripts to work with the arrays now, thanks for pointing that possibility out to me.