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


in reply to Case insensitive hash keys

Hash::Case::Preserve is what you want.
use Hash::Case::Preserve; tie my(%hash), 'Hash::Case::Preserve'; $hash{StraNGeKeY} = 3; print keys %hash; # StraNGeKeY print $hash{strangekey}; # 3 print $hash{STRANGEKEY}; # 3
See especially the note about first or last use case preservation.

Replies are listed 'Best First'.
Re: Re: Case insensitive hash keys
by hmerrill (Friar) on Feb 06, 2004 at 13:20 UTC

    This looks like a perfect solution. However it does require you to download and install a module from CPAN - since Hash::Case::Preserve is not included in the standard perl distribution.

    An alternative would be to pick a case(either upper or lower) to load your hash keys in as - then as you load key/value combinations into the hash, convert your hash key to either upper or lower case(whichever you picked) *before* you load them into the hash. Then when you go to refer to a specific key in the hash, first convert the key to the same case that you loaded them in. This technique will have the same effect as ignoring case. There is no other way that I know of to ignore the case of hash keys.

    Example: my %myhash = (); my $key1 = "MixedCase"; my $lower_key1 = lc($key1); $myhash{$lower_key1} = "Some Value"; if (exists($myhash{lc("MIXEDCASE")})) { print "YES it exists!\n"; } else { print "NO it doesn't exist!\n"; }
    HTH.
      This looks like a perfect solution. However it does require you to download and install a module from CPAN

      My first advice would be to go out of your way to get CPAN.pm working; it is *massively* convenient to be able to solve problems quickly by just grabbing modules from CPAN.

      However, if the OP needs to solve the stated problem without a CPAN module, he should use a case-folded key but store the original case as part of the value. In the example below each value is an anonymous array containing the original (non-case-folded) key and the actual desired value. It would be possible to structure the data in a different way (e.g., to use parallel hashes to store the Keys and the values), but this is one good way.

      my @mixedcasekeys = ('ABC', 'foo', 'ExAbbrev'); sub value { return "This is the value for $_\n"; } my %hash; for (@mixedcasekeys) { $hash{lc $_} = [$_, value($_)]; } showkeys(); print "Adding key: 'Foo'\n"; $hash{lc 'Foo'} = ['Foo', value('Foo')]; showkeys(); print "Looping over the keys and showing the values:\n"; for $k (sort map {$hash{$_}[0]} keys %hash) { my $v = $hash{lc $k}[1]; print "$k => $v\n"; } sub showkeys { print "'Keys' in mixed case: " . (join ' ', map {$hash{$_}[0]} keys %hash) . "\n"; }

      As you can see, solving little problems like this by hand is just a bit more complicated than grabbing a module off of the CPAN. Each and every time you have a little problem like this, solving it by hand will be more complicated than grabbing a module off of the CPAN. Getting CPAN.pm set up once is more complex than solving one or two such problems, but if you have Perl stuff to do in the future, CPAN will pay you back for your trouble quite quickly.


      $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/