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

Can a hash name have the same value twice.

by DavidBer (Initiate)
on May 02, 2000 at 23:02 UTC ( [id://9968]=perlquestion: print w/replies, xml ) Need Help??

DavidBer has asked for the wisdom of the Perl Monks concerning the following question: (hashes)

I am trying to read in a file. The structure of the file is city:country. What I need to do is to show cities within a country. My thought was to read the file into a hash, with it like this:

US:Miami
US:New York
US:Chicago

I understand that an @ array basically uses a number as the identifier of the value. How does a hash do it?

Originally posted as a Categorized Question.

  • Comment on Can a hash name have the same value twice.

Replies are listed 'Best First'.
Re: Can a hash name have the same value twice.
by reptile (Monk) on May 03, 2000 at 00:58 UTC

    There is a much better answer in this case than storing multiple bits of information in the hash keys. I would personally never do that unless I absolutely had to. The example given in this question is actually a really simple data structure: One name to Multiple values, or in perl, a hash whose values are array references. Enough lecturing now.

    my %countries = (); my $foo = "US:New York"; my ($country, $city) = (split /:/, $foo); push @{ $countries{$country} }, $city;

    This code assumes you understand references in perl.

    Then to print all the cities within the country:

    foreach my $city (@{$countries{$country}}) { print "$city\n"; }

    It's trivial to include even more information than that as well; turn that array reference into a hash reference by city, containing maybe another hash reference with even more information or an array with a list of people who live there.

Re: Can a hash name have the same value twice.
by chromatic (Archbishop) on May 03, 2000 at 07:19 UTC
    If you need to store more information, consider a more complex data structure. reptile suggests a hash of lists. I would choose a hash of hashes.
    my %data = ( 'US' => { Florida => 'Miami', Illinois => 'Chicago', New York => 'New York City' }, 'Canada' => { British Columbia => 'Alberta', Saskatchewan => 'Saskatoon', Ontario => 'Toronto' } );
    The appropriate perldoc pages are perldsc and perlref.

    (Oh, a hash is an associative array. That means that it takes the first element -- New York, for example -- and runs it through a hashing algorithm to generate a unique index, which helps it locate the key -- New York City -- in an internal data structure. If the hashing algorithm is good, "New York" will always come up with the same hash value, which is why duplicate keys are not very useful.)

Re: Can a hash name have the same value twice.
by Roger (Parson) on Sep 10, 2003 at 03:59 UTC
    Create a two dimensional hash like this:
    @cities = qw/ US:Miami AU:Melbourne US:Chicago /; map {my($co,$ci)=split/:/,$_; $n{$co}{$ci}=1 } @cities; foreach $x (sort keys %n) { foreach (sort keys %{$n{$x}}) { printf "$x - $_\n"; } }
    Which will print out:

    AU - Melbourne
    US - Chicago
    US - Miami
Re: Can a hash name have the same value twice.
by turnstep (Parson) on May 02, 2000 at 23:35 UTC
    Here is a simple way to do it:
    open(MYFILE, "$cityfile") || die "Could not open $cityfile: $!\n"; while(<MYFILE>) { chomp; ($city, $country) = split(/:/, $_); $place{$country} .= "$city#"; } close(MYFILE); for $x (keys %place) { print "$x:\n"; for (split(/#/, $place{$x})) { print "\t$_\n"; } }
Re: Can a hash name have the same value twice.
by Roger (Parson) on Sep 10, 2003 at 04:05 UTC
    This is to amend my previous post, the foreach loop can certainly be rewritten with a one liner:
    map {my $key=$_;map {print "$key - $_\n"} sort keys %{$n{$_}} } sort keys %n;
Re: Can a hash name have the same value twice.
by Bloodelf (Beadle) on Jun 19, 2001 at 02:53 UTC
    If you want to put all of the the values for each key together, then give this a go.(I'm Assuming the file is in the above format.)
    open (FILE,"c:/file.txt"); %hash=(); while (<FILE>) {chomp; split /:/; if ($hash{$_[0]}){$hash{$_[0]}.=",$_[1]";} else {$hash{$_[0]}=$_[1];} }
      HI, I'm not able to execute the script u have written. I have a requirement like this: original file: 38881,408 38884,596 38884,597 38884,607 38884,608 38884,609 38884,615 output expected: 38881:408 38884:596,597,607,608,609,615 Could you plz. help me to get this output done
Re: Can a hash name have the same value twice.
by Anonymous Monk on Mar 24, 2004 at 02:09 UTC

    Re: Can a hash name have the same value twice.

    Originally posted as a Categorized Answer.

Re: Can a hash name have the same value twice.
by Doraemon (Beadle) on May 11, 2004 at 13:35 UTC
    Personally i think Roger's idea on the hash (with empty value) not quite efficient (but his code looks good, though :) ). I prefer the previous approach (reptile)

    Originally posted as a Categorized Answer.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (6)
As of 2024-04-19 12:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found