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

Hi, I'm learning Perl, and I've got a question, how could I compare a STDIN from the user and a string inside an array like I tried to do. I did this but doesn't work -->

my @answer=( "Bad", "Good", "Not good enough" ); chomp(my $user_answer=<STDIN>); if ($user_answer eq @answer){ print "Ok\n"; }

I know that I can print a value inside the array with [] , but I don't know if there's any way to try them all...

Replies are listed 'Best First'.
Re: Comparison between a string and an array
by pme (Monsignor) on May 04, 2015 at 10:42 UTC
Re: Comparison between a string and an array
by choroba (Cardinal) on May 04, 2015 at 10:35 UTC
    Hi Eth443, welcome to the Monastery!

    This is a FAQ.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Thanks you very much, thanks all of you, it's working properly. And thanks for the welcome!

      Wow almost I forget.What is this advice: Smartmatch is experimental. What does mean?

        It means that the ~~ operator's behaviour might change in a future release, or it could be completely removed. You shouldn't rely on it in production code. Fortunately, there're alternatives listed in the FAQ.
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Comparison between a string and an array
by Laurent_R (Canon) on May 04, 2015 at 18:55 UTC
    Modifying slightly your code (and avoiding smart match):
    my %answer = map {$_, 1} ( "Bad", "Good", "Not good enough" ); chomp(my $user_answer=<STDIN>); if (defined $answer{$user_answer}) { print "Ok\n"; }

    Je suis Charlie.
Re: Comparison between a string and an array
by edimusrex (Monk) on May 04, 2015 at 20:07 UTC
    Try this
    my @answer=( "Bad", "Good", "Not good enough" ); chomp(my $user_answer=<STDIN>); if (grep (/\b$user_answer\b/, @answer)){ print "Ok\n"; }
    using regex to match your input with the array elements, it's important to use word boundaries (\b) around the variable or a user input of "Ba" will match "Bad" etc

      I tried putting Ba and doesn't match as you said, actually for me it's working, but I will considere your answer/reflexion for future codes. Thanks

        I was meaning that with out the \b (to escape word boundaries) "Ba" would match Bad meaning


        $match = 'Ba'; @array = ('Bad','Good','Whatever'); if (grep(/$match/, @array)) { print "Yippie!\n"; } else { print "No Match\n"; }

        If you enclosed the variable $match in word boundaries as followed

        grep(/\b$match\b/, @array)

        It would no longer match do to the fact that the match must match the exact string passed

Re: Comparison between a string and an array
by sir_jeff (Novice) on Sep 25, 2016 at 08:54 UTC

    My 2-cents worth....
    Before I discovered smart matching I used to just loop the array and search for a match.
    After reading these answers I thought hey maybe I could use 'join'.
    In the code below I have 6 methods including smart match ~~ as proof-of-concept.
    I run each of the 6 methods on 3 different match variables.
    -- sorry about the golf-style code, it's just how I roll --

    my$match,$res; my@array=("Nice","Bad","Good","Not good enough"); foreach$match("Ba","bad","Bad"){ #method submitted by edimusrex using greb with \b boundaries if(grep(/\b$match\b/,@array)){$res="y"}else{$res="n"} print"1: $match : $res\n"; #similar as first method but using ^ start and $ finish matching if(grep(/^$match$/,@array)){$res="y"}else{$res="n"} print"2: $match : $res\n"; #smart matching just for POC if($match~~@array){$res="y"}else{$res="n"} print"3: $match : $res\n"; #the long method I used to use looping the array $res="n"; foreach(@array){if($_ eq $match){$res="y"}} print"4: $match : $res\n"; #joining the array and adding ~ to start and finish as boundaries if(("~".join("~",@array)."~")=~/~$match~/){$res="y"}else{$res="n"} print"5: $match : $res\n"; #same as above but using \b boundaries instead of hard-coding ~ if(join("~",@array)=~/\b$match\b/){$res="y"}else{$res="n"} print"6: $match : $res\n\n"; }

    results (perl v5.24.0 on Win7) :

    1: Ba : n 2: Ba : n 3: Ba : n 4: Ba : n 5: Ba : n 6: Ba : n 1: bad : n 2: bad : n 3: bad : n 4: bad : n 5: bad : n 6: bad : n 1: Bad : y 2: Bad : y 3: Bad : y 4: Bad : y 5: Bad : y 6: Bad : y
      my$match,$res;

      my has higher precedence than comma, so $res is an undeclared variable there. And since you're not using strict, why bother declaring at all?

        I thought my$match,$res; the same as writing

        my$match; my$res;

        I'm just declaring both on one line.
        Anyway it was just a rough (working) code fart. If I was gonna bother with strict then I'd even add the shebang! and a "use warning" , but yeah nah, point taken. I'll leave out the local or global declarations next time to make it more obvious, cheers -SJ-