Reputation: 195
A program reads a very large dictionary-style TXT file into a hash. Sometimes, there is a lower case version of a key that is preferable. My solution below is clumsy because it searches twice even if we already know the lc
version exists:
if ( exists $hash{ lc $key } ) {
$key = lc $key;
}
if ( exists $hash{ $key } ) {
# lot of code involving $key
}
else {
# the key doesn't exist, other code
}
Is there a way to avoid two exists
tests? If lc $key
exists I want to do the identical code to it as in the second if
but I need to know which version, lc
or not, of $key
to use. I'm hoping to condense it to one if-else
pair.
Knowing the case of the valid key is important for the rest of the program since it is used to look up information in another hash.
Upvotes: 0
Views: 82
Reputation: 386696
if ( my ($real_key) = grep { exists($hash{$_}) } lc($key), $key ) {
...
} else {
...
}
or
my $real_key =
exists($hash{ lc($key) }) ? lc($key)
: exists($hash{ $key }) ? $key
: undef;
if (defined($real_key)) {
...
} else {
...
}
Sure, it still searches twice, but so what? You could use List::Utils's first
, but I think replacing a hash lookup with a sub call could actually slow down the code!
Upvotes: 3
Reputation: 40778
You could also do this:
$key = do { my $temp = lc $key; exists $hash{$temp} ? $temp
: ( exists $hash{$key} ? $key : undef) };
if ( defined $key ) {
# lot of code involving $key
}
else {
# the key doesn't exist, other code
}
Upvotes: 0
Reputation: 6553
You could use first
from List::Util. It will return the first list element where the result from the code block is a true value, or undef
if the block never returns true.
use List::Util qw(first);
$key = first { exists($hash{$_}) } lc($key), $key;
if (defined($key)) {
# ...
}
Upvotes: 0