in reply to Merging Complex Hashes

You could use Algorithm::EquivalenceSets.

#!/usr/bin/perl -w use strict; use warnings; use Data::Dumper; use Algorithm::EquivalenceSets; my %groupOfBact = ( group1 => { strain1=>1, strain2=>1, strain4=>1, } , group2 => { strain3=>1, strain4=>1, strain5=>1, } , group3 => { strain6=>1, strain7=>1, }, ); print Dumper(\%groupOfBact); my @sets = map { [ keys %{$groupOfBact{$_}} ] } keys %groupOfBact; print Dumper(\@sets); my @equiv_sets = equivalence_sets(\@sets); print Dumper(\@equiv_sets);

produces

$VAR1 = { 'group2' => { 'strain5' => 1, 'strain3' => 1, 'strain4' => 1 }, 'group1' => { 'strain2' => 1, 'strain4' => 1, 'strain1' => 1 }, 'group3' => { 'strain7' => 1, 'strain6' => 1 } }; $VAR1 = [ [ 'strain5', 'strain3', 'strain4' ], [ 'strain2', 'strain4', 'strain1' ], [ 'strain7', 'strain6' ] ]; $VAR1 = [ [ 'strain7', 'strain6' ], [ 'strain2', 'strain4', 'strain1', 'strain5', 'strain3' ] ];

There are other modules that might be helpful, depending on what you are wanting to do: Graph::TransitiveClosure, Graph::AdjacencyMatrix, etc.

update: Here is an example using Graph:

#!/usr/bin/perl -w use strict; use warnings; use Data::Dumper; use Graph; my %groupOfBact = ( group1 => { strain1=>1, strain2=>1, strain4=>1, } , group2 => { strain3=>1, strain4=>1, strain5=>1, } , group3 => { strain6=>1, strain7=>1, }, ); print Dumper(\%groupOfBact); my $graph = Graph::Undirected->new; foreach my $group (keys %groupOfBact) { foreach my $strain (keys %{$groupOfBact{$group}}) { $graph->add_edge($group, $strain); } } my @cc = $graph->connected_components(); print Dumper(\@cc);

Which produces

$VAR1 = { 'group2' => { 'strain5' => 1, 'strain3' => 1, 'strain4' => 1 }, 'group1' => { 'strain2' => 1, 'strain4' => 1, 'strain1' => 1 }, 'group3' => { 'strain7' => 1, 'strain6' => 1 } }; $VAR1 = [ [ 'strain7', 'group3', 'strain6' ], [ 'strain3', 'group2', 'strain5', 'strain4', 'group1', 'strain1', 'strain2' ] ];

The Graph module gives you many options for entering your data and analyzing it.

Replies are listed 'Best First'.
Re^2: Merging Complex Hashes
by jpearl (Scribe) on Mar 11, 2009 at 20:39 UTC
    Thank you all! Algorithm::EquivalenceSets is perfect.

    Unfortunately I broke it when trying to install with CPAN. Devel::CheckOS is a pre-req and I think I accidentally hit "no" when I should have hit "yes" (it asked if I was running unix directly after asking if I was running linux! how was I supposed to know the correct answer was "yes"??). Anyway, now it won't let me install it. "clean Devel::CheckOS" doesn't appear to work. Oh well, I'll figure it out eventually. Thanks again for all your help.

      You can try cd ~/.cpan/build/Devel-CheckOS* then perl Makefile.PL. This should take you through the set of questions again and let you set it up right. I just accepted all the defaults, despite wondering whether Linux is Unix. Then the usual make, make test and make install.

        Thanks ig, got it working. Thank you again for all your help, there is very little more satisfying than changing 15+ lines of confusing code into 2 clear ones ;-)