Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the idiomatic way in Perl to determine whether a string variable matches a string in a list?

Tags:

list

hash

perl

Part of the specification says "Some names are special, e.g. Hughie, Dewey, Louis, and Donald. Other names may be added over the lifetime of the project at arbitrary times. Whenever you input one of those names, play quack.wav."

I could write ...

while (<>) {
    if ($_ =~ /Hughie|Dewey|Louis/) {
        quack() ;
    }
    elsif ($_ =~ /Donald/ {
        quack() ;
        you_re_fired_apprentice() ; # Easter egg don't tell QA
    }
}

... but though untaxing to implement, it looks WTF-y: Where's the binary search? What if there were a sudden stupendous increase in the number of duck names? It would not scale at all!

I could create empty files using those names in a temporary directory, and then use the "file exists" API, but that seems roundabout, and I would have to be sure they were deleted at the end.

Surely there is a better way?

like image 957
Thomas L Holaday Avatar asked Jan 31 '11 22:01

Thomas L Holaday


1 Answers

You could write that, but you should write this:

my %ducks = map {$_ => 1} qw(Hughie Dewey Louis);

while (<>) {
    if ($ducks{$_}) {
        quack() ;
    }
    elsif ($_ eq 'Donald') {
        quack() ;
        you_re_fired_apprentice() ; # Easter egg don't tell QA
    }
}

Creating the hash takes a little bit of time, but not more than O(n). Lookup with a hash is O(1) though, so it is much more efficient than sequential search (via grep or a regex with alternation) assuming you will be checking for more than one or two items.

By the way, the regex that you have will match the words anywhere in the search string. You need to add start and end anchors if you want an exact match.

like image 142
Eric Strom Avatar answered Oct 11 '22 03:10

Eric Strom