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

Dear Monks,

I just saw there are tons of array search questions, but I couldn't find what I was looking for. I just show the piece of code for which I hoped it could work:
$a[0] = "a" ; $a[1] = "c" ; $a[2] = "abc" ; $a[3] = "b" ; ($f) = grep {$a[$_] =~ /^abc$/} 0..$#a) ? 1 : 0; if ( $f ) { print "YES\n" ; }
So, I only want $f to be 1 if the text 'abc' is present inside 1 of the array elements, or else $f should be zero!
Any suggestions ?

Thanks
Luca

Replies are listed 'Best First'.
Re: Array seach
by ikegami (Patriarch) on Feb 17, 2006 at 18:40 UTC

    First, $_ eq 'abc' is faster than /^abc$/.

    If you want 0 or 1:

    my $f = !!grep { $_ eq 'abc' } @a; if ($f) { ... }

    True or false will probably suffice:

    my $f = grep { $_ eq 'abc' } @a; if ($f) { ... }

    You can get rid of the flag entirely:

    if (grep { $_ eq 'abc' } @a) { ... }

      More important than that it’s faster is that it expresses what happens more directly. With the pattern match, you have to mentally parse the pattern to figure out what is going on. $_ eq 'abc' is much quicker to read.

      Makeshifts last the longest.

      nice examples!, but what does !! do ?

      Luca

        It's two negation operators. In scalar context ("!" imposes a scalar context), grep returns the number of matching elements. Negating this twice converts zero to false, and non-zero to true. False is 0 when used as a number. True is 1 when used as a number.

        For example,

        | Ex. 1 | Ex. 2 -------------------+-------+------ grep returns | 4 | 0 1st negation op | false | true 2nd negation op | true | false When used as a num | 1 | 0 When used as a str | '1' | ''
Re: Array seach
by InfiniteSilence (Curate) on Feb 17, 2006 at 17:26 UTC
    Why does it need to actually have a zero or a one as the result? If you just check the result of the grep you will know whether the element exists or not:

    #!/usr/bin/perl -w use strict; my @a; my $f; $a[0] = "a" ; $a[1] = "c" ; $a[2] = "abcd" ; $a[3] = "b" ; ($f) = grep {$a[$_] =~ /^abc$/} (0..$#a);# ? 1 : 0; if ( $f ) { print "YES\n" ; } 1;
    Therefore can be greatly simplified to become:

    #!/usr/bin/perl -w use strict; my (@f) = qw|a ab abc abcd|; if (grep {/Zabc/} @f){ print 'YES!'; } 1;
    Also, if you read grep's perldoc, you will learn more about it:
    In scalar context, returns the number of times the expression was true.

    Celebrate Intellectual Diversity