Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

If any element-in-array comparision

by naturalsciences (Beadle)
on Jan 27, 2012 at 15:57 UTC ( #950396=perlquestion: print w/ replies, xml ) Need Help??
naturalsciences has asked for the wisdom of the Perl Monks concerning the following question:

hello, I had a need to evaluate a list or an array. So that if any element within this list would be bigger than 0.1 I would print the whole list. It would be possible to do it by means of counter. (Initially set to something(like zero), then a loop through whole list, in case a comparison succeeds ++ to counter, later I can check it, if its gotten bigger or not) Still I was wondering if there is a more elegant solution, maybe there already is some tool in Perl itself?

Comment on If any element-in-array comparision
Re: If any element-in-array comparision
by chessgui (Scribe) on Jan 27, 2012 at 16:01 UTC
    I forsee that the 'map' and 'grep' guys will come in on this one.
Re: If any element-in-array comparision
by fisher (Priest) on Jan 27, 2012 at 16:06 UTC
    you need to go through given list at least once, but not with counter. You loop through whole list, preparing your output data, and if there is element bigger than 0.1 you trigger some variable to, say, 1. No need in counter, but in trigger.

    Also, you can output the whole array with 'print' and 'join', in one line of code.

      I learned at this site that there are utilities for lists. For example to get the maximum value of a list:
      use List::UtilsBy qw(max_by); my @list=(0.03,0.04,0.01); my $max=max_by {$_} @list; print "Maximum of ",join(',',@list)," is $max\n";
        Yes, you're of course right. By stating that 'you need to go through list' I meant that general algorythm goes through list at least once and this is a must. What you will use for that task - List::Utils or grep or your own cycle - isn't important in this context.

        And of course I can provide some code snippets, but I feel that this would be a bad idea for OP who doesn't show us a line of his own.
Re: If any element-in-array comparision
by choroba (Abbot) on Jan 27, 2012 at 16:21 UTC
    for (@list) { if ($_ > 0.1) { $seen = 1; last; } } print "@list" if $seen;
    Or use List::Util::first:
    use List::Util qw/first/; print "@list" if first { $_ > 0.1 } @list;
Re: If any element-in-array comparision
by davido (Archbishop) on Jan 27, 2012 at 17:53 UTC

    When the problem description contains the word "any" in the context of a list of items, List::MoreUtils::any seems like an ideal fit.

    use List::MoreUtils qw{ any }; print "@array\n" if any { $_ > 0.1 } @array;

    I've seen List:Util::first mentioned a couple of times, and agree that will work fine. I recommend List::MoreUtils::any, however, as its meaning and intent is clearer since it has a name that matches the problem.


    Dave

      I've seen List:Util::first mentioned a couple of times, and agree that will work fine. I recommend List::MoreUtils::any, however, as its meaning and intent is clearer since it has a name that matches the problem.

      (++) though I'd like to put it stronger: although it doesn't make a difference in this particular case, List::MoreUtils::any is the only one that will work in general even when the value to search does not evaluate to boolean true.

      This will not work:

      print "@a\n" if List::Util::first { 0 == $_ } @a

      This will:

      print "@a\n" if List::MoreUtils::any { 0 == $_ } @a

      If it wasn't for the difference that any returns a boolean "found" while first returns the actual element found, the two might as well be aliases to the same code.

      grep in scalar context will work fine too but if the list is large it may be wasteful because it always goes through the whole list to return the number of matches even if it could stop after the first.

          This will not work:

          print "@a\n" if List::Util::first { 0 == $_ } @a

        When using first as a condition, it's best to wrap it in a defined() to specifically check for the 'not found' case:
        # this always works print "@a\n" if defined(List::Util::first { defined($_) && 0 == $_ } @ +a);

        OTOH, I agree that first clobbers the predicate when checking for undef -- i.e. we can't tell if we found undef:
        # doesn't work print "@a\n" if defined(List::Util::first { !defined($_) } @a);

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2014-08-01 03:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (256 votes), past polls