my %hGroups = ( 'Group1' => { 'ATRG7' => 1, 'ATG2' => 1, 'ATG4' => 1, 'ATG1' => 1 }, 'Group3' => { 'FYCO1' => 1, 'LSM2' => 1 }, 'Group2' => { 'ATG9' => 1, 'ATG1' => 1 } ); #### my %hGroups = map { my $sGenes = $hash{$_}; my $hGroupMembers = { map { $_ => 1 } split(',', $sGenes) }; $_ => $hGroupMembers; } keys %hash; #### my %hNewGroups; oldgroup: foreach my $sGroup (keys %hGroups) { my $hGroupMembers = $hGroups{$sGroup}; # check each new group for genes in common with # current old group ($sGroup) foreach my $sNewGroup (keys %hNewGroups) { # check genes in the old group to see if any are # in the new group ($sNewGroup). # Note: use exists to prevent auto-vivification # (automatic adding) of $sGene to the members hash my $hNewGroupMembers = $hNewGroups{$sNewGroup}; foreach my $sGene (keys %$hGroupMembers) { if (exists($hNewGroupMembers->{$sGene})) { $hNewGroups{$sNewGroup} = { %$hNewGroupMembers , %$hGroupMembers }; next oldgroup; } } } # create a new group, since no gene is in common with # other groups found so far $hNewGroups{$sGroup} = $hGroupMembers; } #### %hNewGroups = ( 'Group1' => { 'ATG9' => 1, 'ATG2' => 1, 'ATRG7' => 1, 'ATG4' => 1, 'ATG1' => 1 }, 'Group3' => { 'FYCO1' => 1, 'LSM2' => 1 } ); #### while (my ($sNewGroup,$hMembers) = each(%hNewGroups)) { print "$sNewGroup: " . join(',', keys %$hMembers) . "\n"; } #### Group1: ATG9,ATG2,ATRG7,ATG4,ATG1 Group3: FYCO1,LSM2