Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Re: extract only smallest numbers

by grep (Monsignor)
on Jul 21, 2007 at 20:48 UTC ( #628025=note: print w/replies, xml ) Need Help??

in reply to extract only smallest numbers

Is there a way of reading the file and printing each name with the smallest number next to it?
Yes, absolutely!

Though, it seems you forgot to post the code you've worked on. I won't assume you wanted someone else to write it for you, so I'll give you some places to look. Then when you have some code that you have written, and have a problem you can ask a question here. (right after you read this)

  • Go take a look at open about reading the file
  • Look at foreach loops to go over the lines in the file
  • Look at split to get the number and name
  • Read about Hashes(associative arrays) to store your results
  • perlop will tell you how to evaluate 'less than'
  • And finally reading print will show you how to print your results

Replies are listed 'Best First'.
Re^2: extract only smallest numbers
by Anonymous Monk on Jul 21, 2007 at 21:09 UTC
    Thank you grep, but my problem is exactly on how to compare the numbers.
    Assuming, for example, that I have the code:
    open FILE, $my_file; while (<FILE>) { $_=~/(.*)\t(.*)/; $name=$1; $code=$2; $hash{$name} = $code; }
    That is as far as I can go...

      Couple of things first.

      • Use strict and warnings
      • Check to see if your open succeeds
      • Use split not a regex when you want to split
      • Indent your code - It makes reading the code easier on you and us
      So your code should look something like (untested):
      use strict; use warnings; open FILE, $my_file or die "Can't open $my_file\n"; my %hash; while (<FILE>) { my ($name, $code) = split(/\t/); }
      Now you have some of the problems fixed. Now you need to test what's in the hash and $code.

      One thing to remember is, that if you have not assigned a value to the hash for that key you'll get undef returned, which evaluates to 0 numerically. Since you are looking for the lowest number you'll want avoid the undef. So check the value from your hash with defined first. If you see that it is not defined, then you know to assign the value of $code whatever it is.

      # Still untested if ( !defined( $hash{$name} ) ) { $hash{$name} = $code; }
      If you have a value defined then check to see whats larger
      # Still untested if ( !defined( $hash{$name} ) or $code < $hash{$name} ) { $hash{$name} = $code; }
      ... if (!exists $hash{$name}) { # unconditionally assign the first entry $hash{$name} = $code; } else { # assign further entries only if smaller... $hash{$name} = $code if $code < $hash{$name}; }
        Yes indeed. Or more concisely, just replace your 1 line:
        $hash{$name} = $code;
        With this single line instead:
        $hash{$name} = $code if !defined $hash{$name} || $code < $hash{$name};
        ie. You assign the latest value only if it's the first value for that key name, or if it's smaller than any previous value so far.

        I'd recommend defined over exists in this case. If the hash key somehow did exist with an undefined value, the exists test would let it through, and then you'd then get a warning (under use warnings) when you got to the 'less than' comparison.

        Using defined instead will avoid this potential banana skin, and give you the correct outcome.

        Doesn't work...
        It prints:
        jim 5 nick 29 george 12
        Thank you anyway....

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://628025]
Jar. Jar!...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (4)
As of 2018-05-25 09:55 GMT
Find Nodes?
    Voting Booth?