Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Looping through a hash where some keys are the same

by GaijinPunch (Pilgrim)
on Feb 18, 2005 at 01:15 UTC ( [id://432157]=perlquestion: print w/replies, xml ) Need Help??

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

Hey Monks:

My (free) provider disabled all CGI (Perl included) b/c some geek hacker attacked in a very malicious way. As such, I had to recode everything in PHP. What a crime, no? Anyways, as I'm out of practice, I'm having trouble with something.

I need to loop through a small hash. Some of the keys are the same though. Seems that everything I try such as either of two of the following won't work. It will grab only one instance in which a key is used, or both instances, but output the same value twice.

Any help?
my %hash = ( "bob" => "section-a", "bob" => "section-b", ); for my $key ( keys %hash ) { my $value = $shit{$key}; print "$key => $value\n"; }
Returns bob => section-a
my %hash = ( "bob" => "section-a", "bob" => "section-b", ); for ( my ( $key, $value ) = each %hash ) { print "$key => $value\n"; }
Returns
bob => section-b
bob => section-b

Replies are listed 'Best First'.
Re: Looping through a hash where some keys are the same
by chromatic (Archbishop) on Feb 18, 2005 at 01:23 UTC

    That's what hashes do. They don't allow duplicate keys. If you really need to store multiple scalars for a single key, you need advanced data structures, such as a hash of array references.

    If you explained the problem you're trying to solve, though, and not the code you've tried to use to solve it, people may be able to give you better answers.

Re: Looping through a hash where some keys are the same
by borisz (Canon) on Feb 18, 2005 at 01:28 UTC
    A hash has only unique keys. You might better use a array.
    my @array = ( [ bob => "section-a"], [ bob => "section-b"] ); for ( @array ) { my ( $a, $b ) = @$_; print "$a => $b\n"; }
    Or use Tie::DxHash this tied hash allows duplicate keys.
    Boris

      Another option would be a hash of arrays, so that each key was unique, but referred to an array of one or more values:

      my %hash = ( 'bob' => [ "section-a", "section-b" ], 'jan' => [ "section-d" ] ); # And to add another.... foreach (qw(section-f section-g)) { push(@{$hash{'paul'}}, $_); } foreach my $k (keys(%hash)) { print "$k => ", join(",", @{$hash{$k}}), "\n"; }

      HTH.

        I'll look into those options. As for what the objective is... it's a script that scours an auction site I frequent b/c their alert system sucks so bad. My hash looks like

        "searchstring" => "section",

        There are some (very few) items that I would want to search for in different sub sections. For now, they're all in the same main section, so I just search that, but it gets like 300 hits or so each day... about half of it crap I don't want to see.

        I assume the smartest approach would to make the keys of the hash the section to search, and the value an array holding the different strings I want to search in that section, no? It'd take a fair bit of rewriting. Not sure if it's worth it at this point, but would be do-able.
Re: Looping through a hash where some keys are the same
by crashtest (Curate) on Feb 18, 2005 at 01:47 UTC
    I almost spit out my water when I read this line from your first code block:
    my $value = $shit{$key};
    From a purely social point of view, it's probably bad form to use dirty language in a computer program. Just doesn't look professional ;-)

    From a code point of view, trying to retrieve a value from one hash with a key from another is also bad form, and might have something to do with your problematic output.
      Oops... how'd that get in there? Errr... yeah, my hash in my original test was named that. As for professional.... it was a 5 line script, and not related to work, so I'm not really going to lose too much sleep over it. Apologies if I offended anyone here though.
Re: Looping through a hash where some keys are the same
by qq (Hermit) on Feb 18, 2005 at 10:29 UTC

    Does anyone else find it surprising that each returns twice? I would have thought that the second assignment of the duplicate key would overwrite the original, and you only get one key/value pair back.

    I appeal to the wise among you...

    #!/usr/bin/perl use Data::Dumper; my %h = ( a => 1, a => 2 ); print Dumper \%h; for ( my($k,$v) = each %h ) { print "$k -> $v\n"; } __END__ $VAR1 = { 'a' => 2 }; a -> 2 a -> 2 # why?
      each is returning a two element list, hence it is looping two times and $k, $v is only set once. It works as expected with a while. See "perldoc -f each".

        I new I was overlooking something obvious - thanks.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (5)
As of 2024-04-24 08:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found