0

I would like to get value from hash of hashes but i do not. My code is :

sub test {
    my $filename = $_[0];
    open INFILE, ${filename} or die $!;
    my %hashCount;
    my @firstline = split('\t',<INFILE>);
    shift(@firstline);
    while (my $line = <INFILE>) 
    {
        my %temp;
        chomp($line);
        my @line = split('\t', $line);
        foreach my $cpt (1..$#line) {
            $temp{$firstline[$cpt-1]}=$line[$cpt];
        }
        $hashCount{$line[0]}={%temp};
    }
    return %hashCount;
}
sub get_hash_of_hash { 
    my $h = shift; 
    foreach my $key (keys %$h) { 
        if( ref $h->{$key}) { 
            get_hash_of_hash( $h->{$key} );
        } 
        else { 
            say $h->{$key};
        } 
    } 
}

And when i display my hash :

$VAR10679 = 'M00967_43_1106_2493_14707';
$VAR10680 = {
          'A' => '1',
          'B' => '0',
          'C' => '1',
          'D' => '0',
          'E' => '0'
        };

My first function return my hash of hashes and i get my specific value with the second function. So I want to get value like that :

my %hashTest = test("FILE.txt"); get_hash_of_hash(%hashTest,"M00967_43_1106_2493_14707","A") //return value '1'

Tof
  • 301
  • 5
  • 17

3 Answers3

1

Your hash holds references to hashes.

You can access them like this:

$hashTest{'M00967_43_1106_2493_14707'}{'A'};

See perlref for more info

Demnogonis
  • 3,172
  • 5
  • 31
  • 45
  • Yer syntax is off. Perl5 sigils are context-dependent; you need to say `$hashTest{M00967_43_1106_2493_14707}{A}`: with a `$`, not a `%`. (oh, both the quotes around keys and the `->` are optional) – amon Jul 15 '13 at 13:22
1

You can either access nested elements like

$hash{keyA}{keyB}

or we can write a function that walks the data structure, like

sub walk {
  my ($hashref, @keys) = @_;
  my $pointer = $hashref;
  for my $key (@keys) {
    if (exists $pointer->{$key}) {
      $pointer = $pointer->{$key};
    } else {
      die "No value at ", join "->", @keys;
    }
  }
  return $pointer;
}

which can be used like

my %hash = (
  'M00967_43_1106_2493_14707' => {
      'A' => '1',
      'B' => '0',
      'C' => '1',
      'D' => '0',
      'E' => '0'
  },
);
say walk(\%hash, 'M00967_43_1106_2493_14707', 'A');

Note: When using Data::Dumper, pass references to the Dump function:

print Dump \%hash; # not print Dump %hash

This is neccessary to show the correct data structure.

amon
  • 57,091
  • 2
  • 89
  • 149
  • Thanks you. it's works with $hash{keyA}{keyB}. But i think my hash of hasheashes is not well established because i have not "=>" in my Dumper hash like you `'M00967_43_1106_2493_14707' =>` – Tof Jul 15 '13 at 13:55
0

Use this subroutine..

sub get_hash_of_hash { 
        my $h = shift; 
        foreach my $key (keys %$h) { 
            if( ref $h->{$key}) { 
                get_hash_of_hash( $h->{$key} );
            } 
            else { 
                print $h->{$key};
            } 
        } 
    }
  • Sorry but i use "use strict;" and i have a error message. I do `my %hashTest = test('FILE.txt'); and then get_hash_of_hash(%hashTest,"M00967_43_1106_2493_14707","Total");` ? – Tof Jul 15 '13 at 12:47
  • Can't use string ("M00967_43_000000000-A3JHG_1_1106"...) as a HASH ref while "strict refs" in use at ./count_table.pl line 30, line 5341. – Tof Jul 15 '13 at 12:54
  • how u r trying to access the hash will u please update with proper code then i can help u i am not bale to understand the question –  Jul 15 '13 at 12:57
  • foreach my $in (keys %$name){ print "$in -- $$name{$in}\n"; } use also try this –  Jul 15 '13 at 13:05
  • @Tof There is a difference between *hashes* and *hash references*. Rahul's code expects a hashref, so pass one like `getHoH(\%hash)`. If a plain hash is used in list context, it is flattened to a list of keys and values, so the first argument the called sub sees is not a hash, but a string (that was formerly a key in your hash). – amon Jul 15 '13 at 13:06
  • Ok, i update my code example. In fact, i want to getHoH(\%hash) take two others arguments getHoH(\%hash,"M00967_43_1106_2493_14707","Total") and return the value. – Tof Jul 15 '13 at 13:17
  • @Tof You may want to explain what these other parameters signify. Are they the keys of various levels? I'm confused because your example data doesn't have a `Total` key. – amon Jul 15 '13 at 13:24
  • and also post u r dumper of the hash –  Jul 15 '13 at 13:26
  • the hash u have posted in not hash of hash –  Jul 15 '13 at 13:27
  • Sorry,it's "A" for example. I want to get the value of "A" (M00967_43_1106_2493_14707 is the key of the first hash and this value is a hash and i want for example the value of the second hash) – Tof Jul 15 '13 at 13:29
  • @Rahul : It's a Dumper of my hash but you are probaly reason : my first hash is %temp and i want to add to the second hash %hashCount – Tof Jul 15 '13 at 13:31
  • u r not able to clarify u r question dude –  Jul 15 '13 at 13:31