Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

Need help on hashes.

by ElMagnifico (Initiate)
on Feb 03, 2008 at 20:10 UTC ( #665855=perlquestion: print w/replies, xml ) Need Help??
ElMagnifico has asked for the wisdom of the Perl Monks concerning the following question:

Bretheren, I seek your guidance. I have read the scriptures but have not found enlightenment. No doubt the answer is there but I understand not the wisdom. I beg thine assistance. (Ok...I'll cut that out. :p)

I have a flat file (with some 185k lines)with values like the following:
"CHEVY","US","UNITED STATES" "MERCEDES","DE","GERMANY" "PEUGOT","FR","FRANCE" "FORD","US","UNITED STATES" "LADA","RU","RUSSIAN FEDERATION" "SATURN",US","UNITED STATES" "ROLLSROYCE","UK","UNITED KINGDOM "BMW","DE","GERMANY" <c> </p> As the file is read via a while() loop I'm putting the country code (i +.e. US, DE, etc.) into a hash.</p> <c> while(<DB>) { @db = split/,/; push(@countries,$db["1]); }

I need to do the following:

  1. If the country code is not in the hash, add it with a value of 1;
  2. If the country code is in the hash, increment the value by 1;
  3. When all the entries are in the hash sort it so that it prints out from highest to lowest.

My questions:

1) Is a hash the proper structure for what I'm trying to do?

2) If so, how do I get it to do what I'd like?

Thank you in advance for your help. My experience is at the beginner level and I sincerely appreciate your help.


ElMagnifico - I work at it so that maybe one day it'll be true! :-D

20080205 Janitored by Corion: Added formatting, code tags, as per Writeup Formatting Tips

Replies are listed 'Best First'.
Re: Need help on hashes.
by moritz (Cardinal) on Feb 03, 2008 at 20:15 UTC
    Although you say that you put the values on a hash, you don't. The code you show us puts them onto an array.
    my %countries; while (<DB>){ my @entries = split m/,/, $_; $countries{$entries[1]}++; } for (reverse sort { $countries{$a} <=> $countries{$b} } keys %countrie +s){ print "$_\t\$countries{$_}\n"; }
    should do the trick (untested).

    Update: no, the \ was not intentional, of course it's print "$_\t$countries{$_}\n";. Thanks cdarke.

      Is the \ in front of the $ in the print statement intentional? That gives:
      "US" $countries{"US"} "DE" $countries{"DE"} "RU" $countries{"RU"} "UK" $countries{"UK"} "FR" $countries{"FR"}
      Also it retains the quotes around the country code. I have:
      my %countries; while (<DB>){ my $entry = (split /","/, $_)[1]; $countries{$entry}++; } for (reverse sort { $countries{$a} <=> $countries{$b} } keys %countrie +s){ print "$_\t$countries{$_}\n"; }
        Thank you all for the responses. The example and the explanation are very informative. Hopefully, I'll not experience (i.e. create) any errors when try it out in my script. :-)

        For the record, this is not a homework assignment as apl implies. It's a reasonable thing to suspect but it's incorrect and I don't want the monks to think I'm taking advantage of their help. I'm a network engineer tasked with making sense out of years worth of accumulated syslog data. My code skills (a little C 10 years ago and sporadic uses of perl over the years) are quite limited. The question about whether or not to use a hash was a sincere inquiry as I wasn't sure if there was a more appropriate structure which to employ.

        Thank you all again for your help. It is sincerely appreciated.

        ElMagnifico - Ask for it in your grocer's freezer.
Re: Need help on hashes.
by apl (Monsignor) on Feb 04, 2008 at 01:09 UTC
    If your homework assignment tells you to use a hash, then you use a hash...
Re: Need help on hashes.
by leighsharpe (Monk) on Feb 04, 2008 at 02:13 UTC
    If $countries{$entries[1]} is undefined, $countries{$entries[1]}++; won't work. Don't you need to
    if ($countries{$entries[1]}) { $countries{$entries[1]}++; } else { $countries{$entries[1]}=1; }
      Actually, no, it isn't necessary to include that if statement.

      Incrementing an undef value is such a common annoyance that recent releases of perl special-case it. It seems to have been documented somewhere between version 5.004 and 5.8.8. Quoting directly from perlop, which is currently for version 5.10.0,

      The auto-increment operator has a little extra builtin magic to it....

      undef is always treated as numeric, and in particular is changed to 0 before incrementing (so that a post-increment of an undef value will return 0 rather than undef).

      (Update:) Now that I think of it, the conversion to boolean in

      if ($countries{$entries[1]}) ...
      is also a special case: undef is being silently converted to false, even when using warnings and strict. If it weren't, you would have to say
      if (defined ($countries{$entries[1]})) ...
      which would also be fairly annoying.

        It's funny, I've gotten so accustomed to this behavior I'd stopped thinking of it as a special case, though I think you could make an argument that it the behavior itself isn't actually, though maybe the lack of warning is.

        Let's be clear about what we mean by "recent" though. The behavior is both present and documented in Perl 5.00503 which was released in 1999.

Re: Need help on hashes.
by ww (Archbishop) on Feb 05, 2008 at 02:44 UTC
    Please read also "the scriptures according to the Monastery" regarding (quasi-) html tags allowed here... and recite 20 Writeup Formatting Tips.

    The </br> tag is amongst my bugaboos, here, as what PM allows/uses does not include that particular construct. Note that <br> is allowed, but the appropriate use of paragraph tags, <p> and </p> often/usually provides better presentation.

    As for your data, it, like code, should be enclosed in code (<c>...</c> or <code>...</code>) tags.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://665855]
Approved by moritz
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (6)
As of 2017-06-26 20:07 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (590 votes). Check out past polls.