in reply to Re: Stuck while learning about the hash
in thread Stuck while learning about the hash

Ok I did that. Sorry, that was a stupid oversight on my part. However, once I did do that, I got the following output:

614 MNH 16.00 614 USED 32.00 614 MNH 16.00 614 USED 32.00 614 PB 50.00 614 MNH 16.00 615 USED 32.00 615 PB 50.00 615 MNH 36.00 615 USED 12.00 615 PB 50.00 615 MNH 36.00 615 USED 12.00 615 PB 50.00 615 MNH 36.00 616 USED 12.00 616 PB 50.00 616 MNH 96.00 616 USED 2.00 616 PB 50.00 616 MNH 96.00 616 USED 2.00 616 PB 10.00 616 MNH 96.00

Not only is that 6 of each number instead of 3, but the order is all messed up. Any idea what's going on here?

Stamp_Guy

Replies are listed 'Best First'.
Re: Re: Re: Stuck while learning about the hash
by mr.nick (Chaplain) on Jun 08, 2001 at 07:46 UTC
    You're getting the repeat because the %items hash isn't unique for each of the "$scottnum". You can fix it easily by putting an undef %items after you print out the hash.
    if (($item[0] ne "") && ($item[1] ne "")){ $items{"$item[0]"} = "$item[1]"; foreach my $key (keys %items) { print "$scottnum\t $key \t $items{$key}\n"; } undef %items; }
    But this probably isn't what you wanted. You probably wanted a hash with a key and a subkey (a hash of hashes). I'm not good at explaining so let me show you instead:
    while(<DB>) { chomp; @record = split(/\t/); $scottnum = $record[0]; @details = split(/\|/, "$record[1]"); foreach $detail (@details) { @item = split(/,/, "$detail"); if (($item[0] ne "") && ($item[1] ne "")){ ########################################### $items{$scottnum}{"$item[0]"} = "$item[1]"; ########################################### } } } foreach my $scottnum (keys %items) { for my $key (keys %{$items{$scottnum}}) { print "$scottnum\t $key \t $items{$scottnum}{$key}\n"; } }
    This way a hash of hashes is created.

    Stylistically, I would have probably done it something like:

    my %info; open(DB, "db.txt") || die "Could not open the database: $!"; while (<DB>) { my @info=split /[\s|,]+/,$_; my $scott=shift @info; while (my $key=shift @info) { $info{$scott}{$key}=shift @info; } } close DB;
    But you are definately on the right track!
      Mr. Nick:
      Thanks, that is exactly what I was looking for. I'm still just barely getting a handle on hashes now. If anyone is willing and able to explain how these hash calls are working, I would be quite interested! Thanks!
      Stamp_Guy
Re: Re: Re: Stuck while learning about the hash
by andreychek (Parson) on Jun 08, 2001 at 08:32 UTC
    > Not only is that 6 of each number instead of 3, but the order is all messed up. Any idea what's going on here?

    A quick note about order -- arrays will stay in the order you assign them in, but hashes may not. If you assign
    $array[0] = "foo"
    Then the value foo will always be in the first position in the array, unless you later reassign it in some way.

    However, hashes are a bit different. Whenever you have a hash, Perl put's them in whatever order it finds easiest to store them in. So if you assign:

    $hash{foo} = "abc"; $hash{bar} = "xyz";
    and you later run:
    @somearray = keys %hash
    You cannot expect the key 'foo' to be returned first and 'bar' to be second. The only way to guarantee your output here is to run the command through something like sort:
    @somearray = sort(keys %hash);
    -Eric