Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Most efficient way of search elements in an array

by sqspat (Acolyte)
on Sep 15, 2009 at 13:59 UTC ( [id://795391]=perlquestion: print w/replies, xml ) Need Help??

sqspat has asked for the wisdom of the Perl Monks concerning the following question:

Hello All, I am trying to find the most efficient way of searching through an array for the value 0 and if it finds a zero it should break out of the search and print a Fail to the test I am running. I found out the hard way that it is not possible to do a pattern match with an array as below because it does not iterate through the elements; ... doooh !!! any suggestions?
my @results_file=(1,1,1,0,1); if (@results_file =~ m/0/) { print"\n--FAIL--"; } else { print "\n--PASS--STATUS\n"; print "\n@results_file\n"; }

Replies are listed 'Best First'.
Re: Most efficient way of search elements in an array
by Corion (Patriarch) on Sep 15, 2009 at 14:06 UTC

    So close, yet so far :)

    If you're using Perl 5.10, you can use the "Smartmatch Operator" ~~ instead of =~ and your program will work:

    use strict; for my $testcase ([1,1,1,0,1],[1,1,1,1,1],[1,10,101]) { my @results_file = @$testcase; if (@results_file ~~ m/0/) { print"\n--FAIL-- @results_file"; } else { print "\n--PASS--STATUS\n"; print "\n@results_file\n"; } }

    The only relevant change is from @results_file =~ /0/ to @results_file ~~ /0/. You might want to consider anchoring your match, so you match only a 0, and not 100, or 101.

      But Smartmatch is smart enough to match on numeric equality:
      >perl -wMstrict -le "for my $ar ( [1, 1, 0, 1], [0], [0, 0, 0], [qw(0)], [qw(00)], [qw(000)], [qw(1 1 0 1)], [1], [], [1, 10, 01, 101, 010], [qw(1 10 01 101 010)], ) { print qq{(@$ar): }, @$ar ~~ 0 ? 'naught' : 'not' } " (1 1 0 1): naught (0): naught (0 0 0): naught (0): naught (00): naught (000): naught (1 1 0 1): naught (1): not (): not (1 10 1 101 8): not (1 10 01 101 010): not
      Update: Added 'numeric string' test cases.
Re: Most efficient way of search elements in an array
by toolic (Bishop) on Sep 15, 2009 at 14:18 UTC
    Use a for loop to cycle through your array elements, and break out of the loop as soon as 0 is found using last:
    use strict; use warnings; my @results_file = (1,1,1,0,1); for (@results_file) { if (/0/) { print "\n--FAIL--\n"; last; } else { print "\n--PASS--STATUS\n"; print "\n$_\n"; } } __END__ --PASS--STATUS 1 --PASS--STATUS 1 --PASS--STATUS 1 --FAIL--

    Update: Or maybe this is the output you were looking for...

    use strict; use warnings; my @results_file = (1,1,1,0,1); my $pass = 1; for (@results_file) { if (/0/) { print "\n--FAIL--\n"; $pass = 0; last; } } if ($pass) { print "\n--PASS--STATUS\n"; print "\n@results_file\n"; } __END__ --FAIL--
      This does it alright ... except I just want one PASS to be printed if the script determines that all the array elements are 1
        Then you want my 2nd example ("Update").

        Also note that my code is equivalent to the pre-5.10 solution offered by Fletch. It wasn't obvious to me from the documentation for List::MoreUtils, until I looked at the source code for any: it does break out of the loop as soon as it finds the first match.

Re: Most efficient way of search elements in an array
by Fletch (Bishop) on Sep 15, 2009 at 14:10 UTC

    Possibly also of interest might be any from List::MoreUtils.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Most efficient way of search elements in an array
by whakka (Hermit) on Sep 15, 2009 at 14:58 UTC
    use Test::More tests => 2; my @not_ok = (1,1,1,0,1); my @ok = (1,1,1,1,1,1); ok( not (grep { $_ == 0 } @$_), 'No zeros' ) for ( \@not_ok, \@ok );
Re: Most efficient way of search elements in an array
by Marshall (Canon) on Sep 15, 2009 at 19:49 UTC
    I don't see the need for super efficiency for an array with 5 or 10 True/False values. Use the scalar value of grep to count the number of "zeroes".
    #!/usr/bin/perl -w use strict; my @results_file=(1,1,1,0,1); print "at least one zero" if (grep{/0/}@results_file); __END__ prints: at least one zero
    numeric compare in the grep will do the same thing:
    print "at least one zero" if (grep {$_ == 0}@results_file);
    Slight modification to your code yields the following.... The grep says "tell me the number of times that '0'(zero) was seen when I looked at all elements of @results_file". Yes, there are ways to "stop counting" when the first "zero" is reached, but for just a couple of dozen things in @results_file, it just won't matter.
    #!/usr/bin/perl -w use strict; my @results_file=(1,1,1,0,1); if (grep {/0/}@results_file ) #if (grep {$_ == 0}@results_file) #numeric value { print"\n--FAIL--"; } else { print "\n--PASS--STATUS\n"; print "\n@results_file\n"; }
Re: Most efficient way of search elements in an array
by ccn (Vicar) on Sep 15, 2009 at 20:04 UTC

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (1)
As of 2024-04-26 02:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found