in reply to without looping, check if $var is found in @list

A loop cannot be avoided, but it can be implicit instead of coded longhand:

my @list = qw/ frog turtle tadpole /; my $find = "turtle"; if( grep { $_ eq $find } @list ) { print "Found $find.\n"; }

This isn't going to be the fastest way to do it, because it iterates through the entire list, even if it finds $find as the first element. For randomly distributed data, a smarter algorithm would quit as soon as the first instance is found, like this:

my $found_flag = 0; foreach my $item ( @list ) { if( $item eq $find ) { $found_flag = 1; last; } } if( $found_flag ) { print "Found $find.\n"; }

Either way, a loop is occurring. With grep, the loop happens behind the scenes. The second method spells it out explicitly, and tells it to exit as soon as the item you're looking for is found. That (on average) ought to be faster.

You could also use List::Util's first() subroutine, like this:

use List::Util; my @list = qw/ this that other /; my $find = "that"; if( first { $_ eq $find } @list ) { print "I found it!\n"; }

I'm not sure how first() is implemented, but it should be implemented such that it exists as soon as it finds the match.


Dave

Replies are listed 'Best First'.
Re^2: without looping, check if $var is found in @list
by Anonymous Monk on Dec 14, 2006 at 02:02 UTC
    I swear there was a smaller solution than this, but I'll use this since it works and does exactly what I was looking for.

    I understand one way or another a loop must be done but I wasn't comfortable using foreach() for my current use of this snippet.

    Thanks!

Re^2: without looping, check if $var is found in @list
by Anonymous Monk on Dec 14, 2006 at 02:34 UTC
    After experimenting with the code I seem to have weird results.

    I am implementing your code into an $sth->fetch. My results SORT OF work. The thing that's odd is if the very first fetch'd row does not match, NOTHING matches.

    However, if I remove any @choice but the first element, all the others work as expected. @choice is populated from a forum field where the user selects a few options via checkboxes.

    while ($sth->fetch) { if( grep { $_ eq $name } @choices ) {
    This behavoir is a little weird and I can't imagine what could be going wrong. Any ideas?
      It really is not clear what you are trying to do (and your extra reply doesn't help much either). Your description ("if the very first row does not match, NOTHING matches") is what I would expect, based on the snippet -- the data coming from the fetch would appear to have no bearing at all on whether your "@choices" array contains a match for the "$name" param.

      Based on the snippet you've presented, it looks like the same condition (with the same data, and therefore producing the same result) is being repeated on every iteration over the "while ()" loop.

      BTW, please consider signing up as a regular PerlMonks user (rather than Anonyous Monk), so you can get notifications of replies to your posts, and can update your posts when you want to (instead of posting more replies). It's harmless.

      I don't think I was clear enough..

      When my DB query prints out it's always in a specific order. If the option in @choices doesn't match the very first row retrieved from my database, everything fails. However, if the first row DOES match something in @choices all the other ones that match the critera work and the ones that don't are discarded as I expect.

      It's just that the first row is being strange, if it doesn't match @choices nothing will.