I have the following text file.
foo1 bam
foo1 bam
foo2 bam
foo1 zip
foo2 boo
foo1 zip
foo3 zip
I would like to make a Hash of Hashes where KEY1 is column one, KEY2 is the sound it makes (column two): bam
, zip
, or boo
, and the VALUE is the number of occurrences of that sound. Such that the data structure is like this:
$VAR1 = {
'foo1' => {
'bam' => [
2
],
'zip' => [
2
],
},
'foo2' => {
'bam' => [
1
],
'boo' => [
1
],
},
'foo3' => {
'zip' => [
1
],
}
}
Here's what I have so far
use strict; use warnings;
open(my $fh, '<', 'file.txt') or die $!;
my %HoH;
while(<$fh>){
chomp;
my @cols = split(/\t/, $_);
my $KEY1 = $cols[0];
my $KEY2 = $cols[1];
push( @{$HoH{$KEY1}{$KEY2}}, 1); # This actually creates a hash of hash of arrays
}
my %HoH_final;
foreach my $KEY1 (%HoH) {
foreach my $KEY2 (keys %HoH{$KEY1}){
my $count = scalar @{$HoH{$KEY1}{$KEY2}}; # get the size of that array
push( @{$HoH_final{$KEY1}{$KEY2}}, $count);
}
}
What do you think?
Don't you actually want the following data structure?
{
'foo1' => {
'bam' => 2,
'zip' => 2,
},
...
}
If so,
while (<$fh>) {
chomp;
my @cols = split /\t/;
++$HoH{ $cols[0] }{ $cols[1] };
}
If you really want the one-element arrays,
while (<$fh>) {
chomp;
my @cols = split /\t/;
++$HoH{ $cols[0] }{ $cols[1] }[0];
}
Is there a reason why each second-level key points to an arrayref instead of the number? I'd recommend doing it like this:
while(<$fh>){
chomp;
my @cols = split(/\t/, $_);
$HoH{ $cols[0] }{ $cols[1] }++;
}
That will increment (++
) the value at each second-level key when it is encountered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With