Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Different hashes?

by Anonymous Monk
on Mar 26, 2004 at 14:47 UTC ( #340027=perlquestion: print w/replies, xml ) Need Help??

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

Monks
I have an inventory (textfile) with the following:
Category ID Name Type Size
=======================================
WaterSports 8765 Drysuit r M-L
WaterSports 8365 Paddle t 45

WinterSports 5231 Snowboard j 85
WinterSports 5281 Gloves r S
Etc..
I want to create a hash of hashes like the following
$VAR1 = { 'WaterSports' => [ '8765', [ 'Drysuit', 'r', 'M-L' ] '8365', [ 'Paddle', 't', '45' ] ] };
But instead my code is creating this, what is wrong?
$VAR1 = { 'WaterSports' => [ '8765', [ 'Drysuit', 'r', 'M-L' ] }; $VAR1 = { 'WaterSports'=> [ '8365', [ 'Paddle', 't', '45' ] ] };
This is my code:
open(INFILE, "products-id.txt")|| die "Cannot open products-id.txt fil +e"; open (OUTPUT,">$output") or die ("Can't open file $output $!"); chomp(my @ProductArray = map { /^\s*$/ ? () : $_ } <INFILE>); close (INFILE); foreach my $line(@ProductArray) { my ($Category, $ID, $Name, $Type, $Size) = split( / /, $line ); %AllProducts = ($Category => [$ID, [$Name, $Type, $Size]]); print OUTPUT Dumper(\%AllProducts); }
Thanks is advance!!

Replies are listed 'Best First'.
Re: Different hashes?
by Fletch (Chancellor) on Mar 26, 2004 at 14:58 UTC

    You're clearing out the entire hash each time through the loop and replacing it with new contents. You want push @{ $AllProducts{ $Category } }, [ $ID, [ $Name, $Type, $Size ] ]. See perldoc perlreftut, perldoc perldsc, and perldoc perllol.

      Fletch and borisz:
      the outer array referencing brackets [ ] are still wrong, take them away and you got it right.

        Actually what he probably really wants is a HOH and should be doing something like:

        $AllProducts{ $Category }->{ $ID } = { name => $Name, type => $Type, s +ize => $Size };

        But that's why he should read perldoc perldsc.

Re: Different hashes?
by tcf22 (Priest) on Mar 26, 2004 at 15:04 UTC
    You are overwriteing the key in %AllProducts every loop. You need to make the hash value an array ref then push onto it.

    Try this:
    foreach my $line(@ProductArray) { my ($Category, $ID, $Name, $Type, $Size) = split( / /, $line ); unless(exists $AllProducts{$Category}){ $AllProducts{$Category} = []; } push(@{$AllProducts{$Category}}, $ID, [$Name, $Type, $Size]); print OUTPUT Dumper(\%AllProducts); }

    - Tom

Re: Different hashes?
by borisz (Canon) on Mar 26, 2004 at 15:07 UTC
    #!/usr/bin/perl use Data::Dumper; my %products; while (defined( $_ = <DATA> )){ next if $. <= 2 || /^\s*$/; my @d = split ' '; my $cat = shift @d; my $id = shift @d; push @{$products{$cat}}, [ $id, \@d ]; } print Dumper(\%products); __DATA__ Category ID Name Type Size ======================================= WaterSports 8765 Drysuit r M-L WaterSports 8365 Paddle t 45 WinterSports 5231 Snowboard j 85 WinterSports 5281 Gloves r S
    Boris
Re: Different hashes?
by Happy-the-monk (Canon) on Mar 26, 2004 at 15:03 UTC

    Make the following change to your code:

    -    %AllProducts = ($Category => [$ID, [$Name, $Type, $Size]]);
    +    push @{ AllProducts{$Category} }, ( $ID, [$Name, $Type, $Size] );

    what was wrong?

    1. redefined the hash while looping, thus overwriting it.
    2. made a new array reference instead of pushing onto it.

    Cheers, Sören

Re: Different hashes?
by Anonymous Monk on Mar 26, 2004 at 15:36 UTC
    Thank you Monks and thanks for you comments!! It is working now :)
Different hashes part II
by Anonymous Monk on Mar 26, 2004 at 16:29 UTC
    Hello Monks I just send a message not long ago (different hashes?), and I tried your suggestions. I thought it was working because I run the script with a small textfile, but it is not!! :(
    It is creating a new hash, adding a new record at the time. it's exponential huge
    $VAR1 = { 'WaterSports' => [ '8765', [ 'Drysuit', 'r', 'M-L' ] }; $VAR1 = { 'WaterSports'=> [ '8765', [ 'Drysuit', 'r', 'M-L' ] '8365', [ 'Paddle', 't', '45' ] ] };
    This is my modify code:
    open(INFILE, "products-id.txt")|| die "Cannot open products-id.txt fil +e"; open (OUTPUT,">$output") or die ("Can't open file $output $!"); chomp(my @ProductArray = map { /^\s*$/ ? () : $_ } <INFILE>); close (INFILE); foreach my $line(@ProductArray) { my ($Category, $ID, $Name, $Type, $Size) = split( / /, $line ); push(@{$AllProducts{$Category}}, $ID, [$Name, $Type, $Size]); print OUTPUT Dumper(\%AllProducts); }
    I also tried this
    push @{$AllProducts{$Category}}, ($ID, [$Name, $Type, $Size]);
    Thanks
      I am trying borisz's solutions, but as well as the others it's taking too much time to execute, so I cancelled it.. but this time the PARTIAL output I am getting is OK, I am not sure it is repeating the whole thing over and over..
      Borisz's script: #!/usr/bin/perl use Data::Dumper; my %products; while (defined( $_ = <DATA> )){ next if $. <= 2 || /^\s*$/; my @d = split ' '; my $cat = shift @d; my $id = shift @d; push @{$products{$cat}}, [ $id, \@d ]; } print Dumper(\%products);
        It is OK, I should not print the dumper(\%product) to the output file, inside the loop mmmmmm sorry about that
      It might have been better to make this a reply or update to your earlier post. Since you seemed to have missed the point of advice that others gave there, I think I'll post a reply there myself, because more information is available there regarding the problem. (In fact, maybe the present thread should be "considered" for removal or relocation.)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://340027]
Approved by ybiC
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (9)
As of 2020-07-04 12:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?