in reply to multiple hash compare, find, create

Here's one way, although it does iterate over all three hashes twice. My brain hasn't quite kicked in yet this Monday morning, so I'm likely seriously overlooking a more efficient way to do it:

First, create a new temporary hash that has takes the count of keys, then using that new hash with the appropriate keys (the ones that have been counted at least three times), append the values from all three hashes into the new %combined hash:

use warnings; use strict; use Data::Dumper; my $num_hashes = 3; my %h1 = ( a => 1, b => 2, c => 3, ); my %h2 = ( a => 4, b => 5, d => 10, ); my %h3 = ( x => 20, p => 15, b => 6, a => 12, ); my %key_list; for my $hash (\%h1, \%h2, \%h3){ $key_list{$_}++ for keys %$hash; } my %combined; for my $hash (\%h1, \%h2, \%h3){ for (keys %key_list){ next if $key_list{$_} < $num_hashes; push @{ $combined{$_} }, $hash->{$_}; } } print Dumper \%combined;

Output:

$VAR1 = { 'b' => [ 2, 5, 6 ], 'a' => [ 1, 4, 12 ] };

Replies are listed 'Best First'.
Re^2: multiple hash compare, find, create
by Eily (Monsignor) on Dec 10, 2018 at 18:54 UTC

    Iterating through the first hash and looking for keys that exist in the two other is enough.

    use strict; use warnings; use Data::Dump 'pp'; my %h1 = ( a => 1, b => 2, c => 3, ); my %h2 = ( a => 4, b => 5, d => 10, ); my %h3 = ( x => 20, p => 15, b => 6, a => 12, ); my %out; for my $key (keys %h1) { next unless exists $h2{$key} and exists $h3{$key}; $out{$key} = [ $h1{$key}, $h2{$key}, $h3{$key} ]; } pp \%out; __END__ { a => [1, 4, 12], b => [2, 5, 6] }
    But seeing the size of the input hashes, I'd say it might be better to do that while constructing the hashes (eg, first build %h1, then iterate through the values of %h2 but only insert the keys that already exist in %h1, and then the same for %h3), if they aren't tied hashes in the first place.

      D'oh!

      I don't know how I didn't think of that! If the first hash keys don't exist in hash2 or hash3, then they key doesn't exist in all three, does it. Likewise, if hash2 or hash3 have keys hash1 doesn't, same. ;) Sheesh, leave me alone and go home Monday...

      OP... This answer by Eily is by far a better, more efficient and more elegant approach than what I presented.

Re^2: multiple hash compare, find, create
by supertaco (Novice) on Dec 10, 2018 at 18:51 UTC
    Thanks @stevieb! I appreciate you looking at this. I might build a small test case and try this out. Thanks again! EDIT: Actually, I like this method. Giving it a go now!