Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Array, element inside limits

by natol44 (Sexton)
on Jun 15, 2009 at 16:04 UTC ( #771699=perlquestion: print w/ replies, xml ) Need Help??
natol44 has asked for the wisdom of the Perl Monks concerning the following question:

Hi!

I have a sorted array of numbers low=>high and need to test IF one of the values is between $a and $b. And if more than one of the values is betwen $a and $b, need to take the higher.

One hour ago, I began to try, so far nothing positive unless long foreach and IF statements... There is probably a faster method?

Thank you for your help!

Comment on Array, element inside limits
Re: Array, element inside limits
by RMGir (Prior) on Jun 15, 2009 at 16:07 UTC
    First, don't use $a and $b in your actual code, unless you're in a sort block. They're semi-reserved names.

    Second, it sounds like simply binary searching your array for your upper bound and finding the first value less than that upper bound should get you your answer, as long as it's greater than your lower bound. No?


    Mike
Re: Array, element inside limits
by Transient (Hermit) on Jun 15, 2009 at 16:17 UTC
    my %results = map { $_ => 1 if ( $low_watermark < $_ && $_ < $high_watermark ) } @all_numbers;

    will get all of the matching numbers
    my @ordered_result_list = sort keys %results; print $ordered_result_list[-1], "\n";
    will get the highest.

    Update: As stated correctly below - this is really what you'd want (or similar) -

    my @results = sort { $a <=> $b } grep { $low_watermark < $_ && $_ < $high_watermark } @all_numbers;.

    Thanks jwkrahn and ikegami!
      my %results = map { $_ => 1 if ( $low_watermark < $_ && $_ < $high_watermark ) } @all_numbers;

      will get all of the matching numbers

      Not if any of the numbers are duplicates because you are storing them in hash keys which will remove duplicates.

      Why not just:

      my @results = grep $low_watermark < $_ && $_ < $high_watermark, @all_n +umbers;
        I assumed an instance of the number was sufficient and that duplicates could be ignored, but you're absolutely right. I think grep would be a better call.

      my @ordered_result_list = sort keys %results;

      That's wrong. You're sorting lexically, so 10 comes before 9.

      print sort 1..10; # 1 10 2 3 4 5 6 7 8 9

      The above is equivalent to

      print sort { $a cmp $b } 1..10; # 1 10 2 3 4 5 6 7 8 9

      You want to sort numerically.

      print sort { $a <=> $b } 1..10; # 1 2 3 4 5 6 7 8 9 10

      Of course, there's no reason to sort the result if you just want the highest.

      use List::Util qw( max ); print max 1..10; # 10

      my %results = map { $_ => 1 if ( $low_watermark < $_ && $_ < $high_wat +ermark ) } @all_numbers;

      That's wrong. You're incorrectly assuming the expression in the map returns nothing when the condition is false.

      $ perl -wle'my %h = map { $_ => 1 if $_ > 5; } 1..3; print 0+keys(%h); +' Odd number of elements in hash assignment at -e line 1. 1

      You wanted:

      my %results = map { if ( $low_watermark < $_ && $_ < $high_watermark ) + { $_ => 1 } else { () } } @all_numbers;

      Or:

      my %results = map { ( $low_watermark < $_ && $_ < $high_watermark ) ? +$_ => 1 : () } @all_numbers;

      But why is a hash involved at all?

      my @results = grep { $low_watermark < $_ && $_ < $high_watermark } @al +l_numbers; print max(@results), "\n";
        For that matter, why use max, since the natol44 specified "a sorted array of numbers"?
        print $results[-1],"\n";
        :)

        Mike

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (9)
As of 2014-07-31 23:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (255 votes), past polls