### Most efficient way of search elements in an array

by sqspat (Acolyte)
 on Sep 15, 2009 at 13:59 UTC 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 (Pope) 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 (Chancellor) 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 (Abbot) 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

Create A New User
Node Status?
node history
Node Type: perlquestion [id://795391]
Approved by moritz
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (2)
As of 2018-04-22 02:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
My travels bear the most uncanny semblance to ...

Results (82 votes). Check out past polls.

Notices?