Do you need to preserve the case of the keys? It might be easiest to convert all keys to lowercase in the hash and then lowercase the keys whenever you do any lookup.
If you do have to keep the case you might create a lookup hash that would just map from the lowercased keys to the original ones and then do a two-step lookup:
and then do the case insensitive lookup like this:my %alt_seqindex; $alt_seqindex{lc $key} = $key while (my ($key) = each %seqindex);
If you do want to hide this from the users you may subclass BerkeleyDB::Hash, somewhat like this:$value = $seqindex{$alt_seqindex{lc $key}};
This implementation will be much quicker than Fletch's since it doesn't search through the whole tied hash each and every time.package BerkeleyDB::Hash::CasePreserve; use BerkeleyDB; use base 'BerkeleyDB::Hash'; my %LCKeys; # to keep the lc $key => $key mapping for all hashes sub TIEHASH { my $obj = &BerkeleyDB::Hash::TIEHASH; my %lckeys; my $key = $obj->FIRSTKEY(); $lckeys{lc $key} = $key; $lckeys{lc $key} = $key while $key = $obj->NEXTKEY($key); $LCKeys{$obj->[0]} = \%lckeys; return $obj; } sub FETCH { my $self = shift; my $key = shift(); $key = $LCKeys{$self->[0]}->{lc $key} or return; return $self->SUPER::FETCH($key); } sub EXISTS { my $self = shift; my $key = shift(); $key = $LCKeys{$self->[0]}->{lc $key} or return; return $self->SUPER::EXISTS($key); } sub STORE { my $self = shift; my ($key, $value) = @_; if (exists $LCKeys{$self->[0]}->{lc $key}) { $key = $LCKeys{$self->[0]}->{lc $key}; } else { $LCKeys{$self->[0]}->{lc $key} = $key; } return $self->SUPER::STORE($key, $value); } sub DESTROY { my $self = shift(); delete $LCKeys{$self->[0]}; } 1;
Jenda
Always code as if the guy who ends up maintaining your code
will be a violent psychopath who knows where you live.
-- Rick Osborne
In reply to Re: Tie one hash two ways?
by Jenda
in thread Tie one hash two ways?
by MrMadScience
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |