http://www.perlmonks.org?node_id=220736

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

Hi perl monks :)

Here is my question ,, I need to search through an Array to
see if somthing matchs one of the elements in the Array.
This is what i have so far whats wrong?

@AllowedRanks("Recruit","General","Captian","Civilian","Airman"); $found=0; foreach $i (@AllowedRanks){ if("$MemberCall" eq "$i"){ $found="1"; } } if($found==1){ &Welcome; }else{ &NotWelcome; }


Please help :)
Thanks in advance!

A*C

Replies are listed 'Best First'.
Re: Looking Through Arrays?
by The_Rev (Acolyte) on Dec 18, 2002 at 02:31 UTC
    It's a good idea to 'use strict', and to turn on the warnings flag
    #!/perl/bin/perl.exe -w use strict; my @AllowedRanks = ('Recruit', 'General', 'Captian', 'Civilian', 'Airm +an'); my $MemberCall = 'General'; foreach my $record (@AllowedRanks) { if("$MemberCall" eq $record) { &Welcome; } else { &NotWelcome; } } sub Welcome { print "Found a match\n"; } sub NotWelcome { print "No Match\n"; }
      Thank you all so very much!

      it works now! :)
Re: Looking Through Arrays?
by jdporter (Paladin) on Dec 18, 2002 at 04:25 UTC
    Others have answered the question, perhaps adequately for the OP's needs.
    However, it bears mentioning that there is a more idiomatic way of testing for set membership that no one has yet mentioned.
    my @AllowedRanks = qw( Recruit General Captain Civilian Airman ); my %allowed_ranks; @allowed_ranks{ @AllowedRanks } = (); # define a set if ( exists $allowed_ranks{ $MemberCall } ) { # test set membershi +p Welcome(); } else { NotWelcome(); }
    This uses hashes as sets. This is quick and easy, because hashes intrinsically support most set-related operations, such as exists.

    jdporter
    ...porque es dificil estar guapo y blanco.

Re: Looking Through Arrays?
by djantzen (Priest) on Dec 18, 2002 at 02:43 UTC

    As others already said, strict and warnings would have stopped you in your tracks long ago. In any case, how about this (taking some liberties with your variable names and assuming your subs are defined already):

    my $member_call = 'Captain'; # or something my @allowed_ranks = qw/Recruit General Captain Civilian Airman/; grep($_ eq $member_call, @allowed_ranks) ? Welcome() : NotWelcome(); # + using grep+ternary operator

    Update: further explanation to address FamousLongAgo's concerns. qw takes a list of strings and allows them to be specified without commas or quotation marks delimiting each. It's nice to use whenever you've got more than a few entries. grep is a function that iterates through a list, setting the global variable $_ to the current element of the list. It evaluates either an expression (as here) or a block, and returns a list of elements from the original list for which the expression was true. Now the ternary operator is short hand for "if x, then y, else z" where "?" means "if" and ":" means "else". Thus, we test to see if grep returned anything, and if so, call Welcome. Otherwise, call NotWelcome.

    Hope that helps, fever

      I worry about posts in this vein ( not to pick on fever, there have been many, by various monks, including myself ), where a question that is clearly from a beginner elicits a dense piece of minimal code. In this case we get grep, qw, implicit assignment to $_ and the ternary operator, all in three lines.

      I'm not against offering challenging answers to help petitioners learn, but challenging should not mean off-putting, right?

      To be fair, perhaps my perception of the petitioner's level is not the same as fever's.

        I agree, far too much code - 3 lines where one will do

        sub check { grep{/^\Q$_[0]\E$/}qw/Recruit General Captain Civilian Airman/ ? W +elcome() : NotWelcome(); }

        or perhaps that was not what you meant... ;-)

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

        Heh, I've never been called a programming showoff before, thanks! But look, he'd already received two helpful answers that were sufficient to set him on the right track. True, my answer is not appropriate for a newbie, but there is plenty of precedent for other monks discussing particular problems at higher levels of difficulty once the petitioner has been assisted.

Re: Looking Through Arrays?
by pg (Canon) on Dec 18, 2002 at 02:34 UTC
    I am obviously not welcomed :-) Your first line did give you a syntax error, didn't it? Other problems, which the compiler will not tell you, are the following:
    1. The quots surrounding $MemberCall and $i are not neccessary, although they do not cause problem in your case.
    2. if you set $found to "1", then you can not use == later, == is for numbers.
    @AllowedRanks = ("Recruit","General","Captian","Civilian","Airman"); $found=0; my $MemberCall = "me"; foreach $i (@AllowedRanks){ if($MemberCall eq $i){ $found=1; } } if($found==1){ &Welcome; }else{ &NotWelcome; } sub Welcome { print "welcome\n"; } sub NotWelcome { print "Notwelcome\n"; }
      if you set $found to "1", then you can not use == later, == is for numbers.

      Please test your advice.

      perl will automagically attempt to convert a scalar value into the appropriate type of scalar (string or number) according to the context. It will cache the converted value in appropriate slot of the SV (scalar data structure), and will set a flag to that effect.

      In this case, it's not necessary to quote the number, but it does not prevent it from being used in numerical comparisons later -- especially as the numeric equality operator forces a numeric conversion.