Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Odd hash problem

by wpahiker (Acolyte)
on Feb 23, 2007 at 14:58 UTC ( [id://601740]=perlquestion: print w/replies, xml ) Need Help??

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

I'm doing a very simple task, loading a file into a hash. The file is a basic zip-code table:
00601PR787ADJUNTAS 00602PR787AGUADA 00603PR787AGUADILLA 00604PR787AGUADILLA 00605PR787AGUADILLA 00606PR787MARICAO 00610PR787ANASCO 00611PR787ANGELES 00612PR787ARECIBO 00613PR787ARECIBO
And the code is pretty straight-forward:
$count = 0; open (ZIPCODE, "<../Files/ZipCodes.txt") or die "Cannot open ZipCode: +$1\n"; while (<ZIPCODE>) { chomp; ($Zip) = substr($_,0,5); ($State) = substr($_,5,2); ($AreaCode) = substr($_,7,3); ($City) = substr($_,10); $ZipDB{$Zip} = "$City|$State|$AreaCode"; $count++; } print "\nStored: $count\n"; $count = 0; foreach $Zip (%ZipDB) { print "$Zip = [$ZipDB{$Zip}]\n"; $count++; } close (ZIPCODE); print "\n$count Zip codes found\n";
When the "foreach" loop runs I get 20 records listed instead of 10:
Stored: 10 00611 = [ANGELES|PR|787] ANGELES|PR|787 = [] 00612 = [ARECIBO|PR|787] ARECIBO|PR|787 = [] 00603 = [AGUADILLA|PR|787] AGUADILLA|PR|787 = [] 00610 = [ANASCO|PR|787] ANASCO|PR|787 = [] 00606 = [MARICAO|PR|787] MARICAO|PR|787 = [] 00601 = [ADJUNTAS|PR|787] ADJUNTAS|PR|787 = [] 00602 = [AGUADA|PR|787] AGUADA|PR|787 = [] 00605 = [AGUADILLA|PR|787] AGUADILLA|PR|787 = [] 00613 = [ARECIBO|PR|787] ARECIBO|PR|787 = [] 00604 = [AGUADILLA|PR|787] AGUADILLA|PR|787 = [] 20 Zip codes found
I am at a total loss as to why this is not working. Mike

Replies are listed 'Best First'.
Re: Odd hash problem
by vagnerr (Prior) on Feb 23, 2007 at 15:02 UTC
    You are using a hash so you need to use
    foreach $Zip (keys(%ZipDB)){
    Rather than
    foreach $Zip (%ZipDB)


    ___________
    Remember that amateurs built Noah's Ark. Professionals built the Titanic.
      Ok, send me into the dungeon, call the inquisitors. Man, do I feel stupid. I've been looking at it all morning and didn't spot that.

      Thanks.

Re: Odd hash problem
by johngg (Canon) on Feb 23, 2007 at 15:55 UTC
    Rather than using a series of substrs you could populate the four variables in one fell swoop using unpack.

    use strict; use warnings; use Data::Dumper; my %zipDB = (); while ( <DATA> ) { chomp; my ($zip, $state, $areaCode, $city) = unpack q{A5 A2 A3 A*}, $_; $zipDB{$zip} = join q{|}, $state, $areaCode, $city; } print Data::Dumper->Dumpxs([\%zipDB], [qw{*zipDB}]); __END__ 00601PR787ADJUNTAS 00602PR787AGUADA 00603PR787AGUADILLA 00604PR787AGUADILLA 00605PR787AGUADILLA 00606PR787MARICAO 00610PR787ANASCO 00611PR787ANGELES 00612PR787ARECIBO 00613PR787ARECIBO

    Here's the output

    %zipDB = ( '00611' => 'PR|787|ANGELES', '00612' => 'PR|787|ARECIBO', '00603' => 'PR|787|AGUADILLA', '00610' => 'PR|787|ANASCO', '00606' => 'PR|787|MARICAO', '00601' => 'PR|787|ADJUNTAS', '00602' => 'PR|787|AGUADA', '00605' => 'PR|787|AGUADILLA', '00613' => 'PR|787|ARECIBO', '00604' => 'PR|787|AGUADILLA' );

    Cheers,

    JohnGG

Re: Odd hash problem
by imp (Priest) on Feb 23, 2007 at 15:16 UTC
    You will save yourself a lot of pain (and most of your hair) by always using strict and warnings, especially when using mixed case variable names.

    It wouldn't have caught this issue, but it will likely catch many others for you.

    Also, you are trying to use '$1' instead of '$!' for the error variable here:

    open (ZIPCODE, "<../Files/ZipCodes.txt") or die "Cannot open ZipCode: +$1\n";
Re: Odd hash problem
by Fletch (Bishop) on Feb 23, 2007 at 15:02 UTC

    Because when you use a hash in list contents it's flattened into a list of the key, value pairs. You want to use keys.

      Thanks to everyone. One more question, if I may. I know you can load an array directly from a file (@array = <FILE>), is there an easy way to load a hash from a file?
        That depends on how the hash was stored.

        You could use Storable to freeze/thaw the hash like this:

        use strict; use warnings; use Storable qw(freeze thaw); use Data::Dumper; my %orig = ( 1 => 2, a => 'b'); my $frozen = freeze(\%orig); print "Frozen: $frozen\n"; my $restored = thaw($frozen); print "Thawed: ", Dumper $restored;
        Or you could be lazy (and insecure) and use Data::Dumper and eval like this:
        use strict; use warnings; use Data::Dumper; $Data::Dumper::Purity = 1; $Data::Dumper::Terse = 1; my %orig = ( 1 => 2, a => 'b'); my $frozen = Dumper(\%orig); print "Frozen: $frozen\n"; my $restored = eval $frozen; print "Thawed: ", Dumper $restored; print "Error: $@\n";
        I wonder if you meant something different from the answers Fletch and imp gave you. Did you perhaps mean, "How can I populate a hash directly from a file of data like that in my OP?" Something like %hash = {some magic here} <FILE>; rather than while(<FILE>){ # do something # $hash{$key} = $value;}. If that was your question the answer is yes and the magic used would be the map function.

        use strict; use warnings; use Data::Dumper; my %zipDB = map { $_->[0], join q{|}, @{$_}[1 .. 3] } map { chomp; [ unpack q{A5 A2 A3 A*}, $_ ] } <DATA>; print Data::Dumper->Dumpxs([\%zipDB], [qw{*zipDB}]); __END__ 00601PR787ADJUNTAS 00602PR787AGUADA 00603PR787AGUADILLA 00604PR787AGUADILLA 00605PR787AGUADILLA 00606PR787MARICAO 00610PR787ANASCO 00611PR787ANGELES 00612PR787ARECIBO 00613PR787ARECIBO

        The output is

        If I have guessed wrong and this isn't what you meant then I hope the post was of interest anyway :)

        Cheers,

        JohnGG

        Store it as Perl code and use do, or use a serialization format such as YAML (and read it in with YAML::Syck).

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (6)
As of 2024-04-24 10:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found