Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Reading data into a hash of hashes.

by sweetblood (Parson)
on Mar 15, 2012 at 17:24 UTC ( #959827=perlquestion: print w/ replies, xml ) Need Help??
sweetblood has asked for the wisdom of the Perl Monks concerning the following question:

It seems I get to do less and less coding these days and as a result I'm have a very hard time figuring out this problem.

I need to read a file in to a hash of hashes, do some stuff and print the data out. There's more to it than that but this is where I'm stuck now. The script will be opening a file delimited with "^" and based on product key it will store the data. Given my code below I'm ending up with only one hash left, and I just can't get the structure in right.

#!/usr/bin/perl -w use strict; use Data::Dumper; my %mdata; # using <DATA> for now open FI, "<", "f:\\cyclecount.txt" or die "open failed $!"; # get file + from ini while (<DATA>) { chomp; next unless (s/\^/\^/g == 4); my @rec = split /\^/; # $mdata{PKEY} = $rec[0]; my $pkey = trim_trailing($rec[0]); %mdata = ( $pkey => { ABC => trim_trailing($rec[1]), DESC => trim_trailing($rec[2]), UNIT => trim_trailing($rec[3]), LOC => trim_trailing($rec[4]) } ) } close FI or warn $!; print Dumper \%mdata; sub trim_trailing { my $s = shift; $s =~ s/\s+$//; return $s } __DATA__ 0V704-B ^B^STERILE OR TOWELS ^CS/20 EA ^A/2/1 0ZS-050 ^B^ZERO WET SPLASHIELD ^EA ^H/2/1 00E7507 ^B^POLYHESIVE II ^CS/50 EA ^H/3/3 00ER320 ^A^APPLIER MULTIPLE CLIP MED/LG ^BX/3 EA ^G/6/4 00H-334 ^B^SUCTION POLY TRAP ^EA ^G/4/5 000V400 ^B^LAP SPONGES ^CS/40 EA ^A/2/1
I should have 6 records but Data::Dumper shows I only have the last:
$VAR1 = { '000V400' => { 'UNIT' => 'CS/40 EA', 'DESC' => 'LAP SPONGES', 'ABC' => 'B', 'LOC' => 'A/2/1' } };
I'm sure I'm missing something obvious, but its been several years since I've done regular coding and months since I've done any perl.

Sweetblood

Comment on Reading data into a hash of hashes.
Select or Download Code
Re: Reading data into a hash of hashes.
by CountZero (Bishop) on Mar 15, 2012 at 17:41 UTC
    This code will re-initalize your hash over and over again:
    %mdata = ( $pkey => { ABC => trim_trailing($rec[1]), DESC => trim_trailing($rec[2]), UNIT => trim_trailing($rec[3]), LOC => trim_trailing($rec[4]) } )
    Try this instead:
    $mdata{$pkey} = { ABC => trim_trailing($rec[1]), DESC => trim_trailing($rec[2]), UNIT => trim_trailing($rec[3]), LOC => trim_trailing($rec[4]) };

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
Re: Reading data into a hash of hashes.
by roboticus (Canon) on Mar 15, 2012 at 17:45 UTC

    sweetblood:

    Line 17 is your problem--you're reassigning the hash, rather than just adding to it. Change this:

    %mdata = ( $pkey => { ABC => trim_trailing($rec[1]), DESC => trim_trailing($rec[2]), UNIT => trim_trailing($rec[3]), LOC => trim_trailing($rec[4]) } )

    to this:

    $mdata{$pkey} = { ABC => trim_trailing($rec[1]), DESC => trim_trailing($rec[2]), UNIT => trim_trailing($rec[3]), LOC => trim_trailing($rec[4]) };

    While you're at it, I'd suggest changing:

    next unless (s/\^/\^/g == 4); my @rec = split /\^/;

    to:

    my @rec = split /\^/; next unless @rec == 5;

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: Reading data into a hash of hashes.
by AnomalousMonk (Monsignor) on Mar 16, 2012 at 01:40 UTC
    ... its been several years since I've done regular coding and months since I've done any perl.

    So coding in Perl is not 'regular' coding?!?   (gasp/shock/horror!)

Re: Reading data into a hash of hashes.
by muppetjones (Novice) on Mar 16, 2012 at 18:59 UTC

    Also, you could avoid the function call to trim_trailing if you changed

    my @rec = split /\^/;

    to

    my @rec = split /\s*\^\s*/;

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (10)
As of 2014-08-20 20:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (124 votes), past polls