sangramjit basu
sangramjit basu

Reputation: 57

unique value in hash while merging their keys

I have a file with tab separated columns like this:

TR1"\t"P0C134

TR2"\t"P0C133

TR2"\t"P0C136

Now I split these into two arrays (one for each column values) then convert them into hashes but I want to remove the duplicates (here its TR2) while merging their right column values...something like this TR2=>P0C133,P0C136...how is it possible?? is there any function to do it in perl??

for($i=0;$i<=scalar@s_arr;$i++)
{
 if($s_arr[$i] eq $s_arr[$i+1])
  { push(@temp,$idx_arr[$i]); }

 else
  { 
   if(@temp eq "") 
    { $s_hash{$s_arr[$i]}=$idx_arr[$i]; }
   else
    {
      $idx_str=join(",",@temp);
      $s_hash{$s_arr[$i]}=$idx_str;
      @temp="";
     }
   }
}

this is code I've written where @s_arr is storing left column values and @idx_arr is storing right column value

Upvotes: 1

Views: 108

Answers (2)

SSN
SSN

Reputation: 886

If you want that same structure output use hash of hash.

#!/usr/bin/perl
use warnings;
use strict;

my @arr = <DATA>;
my %hash;

foreach (@arr)
{
    my ($k,$v) = split(/\s+/,$_);
    chomp $v;
    $hash{$k}{$v}++;
}

foreach my $key1 (keys %hash)
{
    print "$key1=>";
    foreach my $key2 (keys $hash{$key1})
    {
        print "$key2,";
    }
    print "\n";
}

__DATA__
TR1 P0C134
TR2 P0C133
TR2 P0C136

Output is:

TR2=>P0C136,P0C133,
TR1=>P0C134,

Upvotes: 0

stevieb
stevieb

Reputation: 9306

You can avoid using two arrays and perform what you want in one fell swoop treating the left-side value as the hash key and making it an array reference, then pushing the right-side values that correlate with that key onto that aref:

use warnings;
use strict;

use Data::Dumper;

my %hash;

while (<DATA>){
    my ($key, $val) = split;
    push @{ $hash{$key} }, $val;
}

print Dumper \%hash;

__DATA__
TR1 P0C134
TR2 P0C133
TR2 P0C136

Output:

$VAR1 = {
    'TR1' => [
        'P0C134'
    ],
    'TR2' => [
        'P0C133',
        'P0C136'
    ]
};

Upvotes: 4

Related Questions