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

I have a small project I'm working on, and one hangup I've found is checking input against a known hash, in such a manner as to be case-insensitive. I'd like to get it so it will consider Foo, foo, and FOO to be equivalent. I can think of two ways to do this; one of them hard to code right and one of them hard to use right.
#!/usr/bin/perl # Wasteful to use use strict; use warnings; my %known = ("foo" => "FOO", "bar" => "BAR", "baz" => "BAZ"); print "Talk to me, Goose."; my $input = <STDIN>; chomp($input); foreach my $maybe (keys %known) { if ($input =~ /$maybe/i ) { print "You gave us $input, which equates to $known{$input}. Go +od night, and good luck.\n"; last; } else { print "Not a match. YET!\n"; } } #!/usr/bin/perl #picky about its inputs use strict; use warnings; my %known = ("foo" => "FOO", "bar" => "BAR", "baz" => "BAZ"); print "Talk to me, Goose."; my $input = <STDIN>; chomp($input); print "You gave us $input, which equates to $known{$input}. Have a nic +e day.\n";

Replies are listed 'Best First'.
Re: Checking input against known
by BrowserUk (Patriarch) on Aug 02, 2006 at 03:54 UTC

    Why not just uc the input before comparison?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Checking input against known
by duckyd (Hermit) on Aug 02, 2006 at 03:59 UTC
    Since you don't seem to care about what the casing was that the user entered, why not just upper (or lower) case it?
    my @known = qw/FOO BAR BAZ/; print "Talk to me, Goose. "; my $input = <STDIN>; chomp($input); $input = uc $input ; if( grep { $input eq $_ } @known ){ print "You gave us $input, which is known. Have a nice day.\n"; }else{ print "bad input: $input\n"; }
Re: Checking input against known
by GhodMode (Pilgrim) on Aug 02, 2006 at 04:03 UTC

    Does the following code do what you need? It's basically what BrowserUk recommended, but lc is better than uc. (... because I said so!... and, besides, I wrote it before I saw BrowserUk's message! :)) ...

    use strict; use warnings; my %known = ( "foo" => "FOO", "bar" => "BAR", "baz" => "BAZ", ); while ( <STDIN> ) { chomp; my $input = $_; for ( keys %known ) { if ( lc($input) eq $_ ) { print "You gave us $input, which equates to " . $known{lc( +$input)}; print ". Have a nice day\n"; } } }

    --
    -- Ghodmode
    
    Blessed is he who has found his work; let him ask no other blessedness.
    -- Thomas Carlyle
Re: Checking input against known
by McDarren (Abbot) on Aug 02, 2006 at 04:02 UTC
    How about something like this:
    #!/usr/bin/perl -w use strict; my @known = qw( foo bar baz ); print "Talk to me, Goose."; chomp(my $input = <STDIN>); print "You gave me $input"; if (grep { $_ eq lc($input) } @known) { print ", I know about that. Have a nice day.\n"; } else { print ", I don't know that, try again.\n"; }

    That's possibly not super-efficient, as grep has to examine the whole list each time. If that was a concern, then you could make use of the first() function from List::Util.

    Small nit: It's generally considered bad™ coding style to include multiple statements on a single line. Whitespace and newlines are quite affordable these days - use them ;)

    Cheers,
    Darren :)

Re: Checking input against known
by Samy_rio (Vicar) on Aug 02, 2006 at 04:08 UTC

    Hi, If I understood your question correctly then try like this,

    TIMTOWTDI

    use strict; use warnings; my @known = ("foo", "bar", "baz"); print "Talk to me, Goose."; my $input = <STDIN>; chomp($input); my ($in_fla) = grep/^$input$/i, @known; if ($in_fla) { print "You gave us $input, which equates to ".uc($in_fla).". G +ood night, and good luck.\n"; } else { print "Not a match. YET!\n"; } __END__ D:\Workout>perl array.pl Talk to me, Goose.Foo You gave us Foo, which equates to FOO. Good night, and good luck. D:\Workout>perl array.pl Talk to me, Goose.FOO You gave us FOO, which equates to FOO. Good night, and good luck. D:\Workout>perl array.pl Talk to me, Goose.arr Not a match. YET!

    Updated: Thanks McDarren.

    Regards,
    Velusamy R.


    eval"print uc\"\\c$_\""for split'','j)@,/6%@0%2,`e@3!-9v2)/@|6%,53!-9@2~j';

      my ($in_fla) = grep/$input/i, @known;

      That will not work correctly, as it will match any part of the known strings. For example, it would match "fo", "ar", "z", etc.

Re: Checking input against known
by Mandrake (Chaplain) on Aug 02, 2006 at 05:43 UTC
    Since that known values are in a hash, no need to loop through. Just check if the element exists.
    #!/usr/bin/perl -w use strict; my %known = ("foo" => "FOO", "bar" => "BAR", "baz" => "BAZ"); print "Talk to me, Goose."; my $input = <STDIN>; chomp($input); (exists $known{lc $input} && print "You gave us $input, which equates to $known{lc $input}.\n") || print "Not a match" ;