Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

  • Trying to dynamically create hash of hash as i read from a file
  • while(<FH>){ $line=$_; chomp($line); @values=split(/,/,$line); @type_val=splice(@values,3,2); $ref_a=\@type_val; ($type_value,$key_type)=split(/\./,$values[2]); push(@{$hoh{$key_type}},$type_value); #works fine push(@{$hoh{$key_type{$type_value}}},$ref_a); #Does NOT WORK }
    The error i get is 'cant coerce array into hash'. any help would be appreciated. thanks

    DATA - the file consists lines like :

  • abc,def,excel1.xls,12,some,time
  • hj,uyi,excel2.xls,12,more,time2
  • Replies are listed 'Best First'.
    Re: Hashes of hashes
    by arkturuz (Curate) on Jan 15, 2007 at 10:25 UTC
      Is this what you're looking for?
      use strict; use Data::Dumper; my %hoh; while(<DATA>){ my $line=$_; chomp($line); my @values=split(/,/,$line); my @type_val=splice(@values,3,2); my $ref_a=\@type_val; my ($type_value,$key_type)=split(/\./,$values[2]); push(@{$hoh{$key_type}},$type_value); #works fine push(@{$hoh{$key_type}},{$type_value},$ref_a); #Does NOT WORK } print Dumper(\%hoh); __DATA__ abc,def,excel1.xls,12,some,time hj,uyi,excel2.xls,12,more,time2
      Result:
      $VAR1 = { '' => [ undef, { '' => undef }, [] ], 'xls' => [ 'excel1', { 'excel1' => undef }, [ '12', 'some' ], 'excel2', { 'excel2' => undef }, [ '12', 'more' ] ] };
      • Looking for :
      • <li> RESULT</li> $VAR1 = { 'xls' => [ 'excel1', { 'excel1'=>['12','some'] } 'excel2', { 'excel2'=>[12,more] } ] };

        I have a lot of file typeslike xls,doc.... I want "file_type" to be the firt key which contains all the files of that types and each of these files second keys which in turn have an array as its value.

      • Thanks
          You were nearly there!
          #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my %hoh; while(<DATA>){ my $line=$_; chomp($line); my @values=split(/,/,$line); my @type_val=splice(@values,3,2); my ($type_value,$key_type)=split(/\./,$values[2]); $hoh{$key_type}{$type_value} = [@type_val]; } print Dumper \%hoh; __DATA__ abc,def,excel1.xls,12,some,time hj,uyi,excel2.xls,12,more,time2
          output:
          ---------- Capture Output ---------- > "c:\perl\bin\perl.exe" _new.pl $VAR1 = { 'xls' => { 'excel2' => [ '12', 'more' ], 'excel1' => [ '12', 'some' ] } }; > Terminated with exit code 0.
    Re: Hashes of hashes
    by inman (Curate) on Jan 15, 2007 at 14:27 UTC
      Example solution with comments
      #! /usr/bin/perl -w use strict; use Data::Dumper; my %hash; while (<DATA>){ # remove the newline chomp; # Split the data into an array my @data = split /,/,$_; # Match the filename and extension if ($data[2] =~ /(\w+)\.(\w+)/){ # push push @{ # onto an array refered to by the hash value $hash{lc $2}{$1} }, # array values using a slice @data[3,4]; } } print Dumper(\%hash); __DATA__ abc,def,excel1.xls,12,some,time hj,uyi,excel2.xls,12,more,time2 gh,ty,word1.doc,234,thing,time2 ksdj,hsjh,word2.doc,334,is,time3
      yields
      $VAR1 = { 'doc' => { 'word2' => [ '334', 'is' ], 'word1' => [ '234', 'thing' ] }, 'xls' => { 'excel2' => [ '12', 'more' ], 'excel1' => [ '12', 'some' ] } };
      • neat !!
      • Thanks
    Re: Hashes of hashes
    by wfsp (Abbot) on Jan 15, 2007 at 10:47 UTC
      Could you give us an idea of what you expect your data structure to look like? A few more lines of data would be useful too.
        __DATA__
      • abc,def,excel1.xls,12,some,time
      • hj,uyi,excel2.xls,12,more,time2
      • gh,ty,word1.doc,234,thing,time2
      • ksdj,hsjh,word2.doc,334,is,time3
      • Result like:

        xls=>[excel1,excel2] excel1=>[12,some] excel2=>[12,more] doc=>[word1,word2] word1=>[234,thing] word2=>[334,is]
          hmmm, that's not quite the same as what you have here. Is my earlier reply close to what you want?