"Gavin Sinclair" <gsinclair / soyabean.com.au> wrote in message news:<021001c26395$ab204190$b14332d2@nosedog>... > ----- Original Message ----- > From: <dblack / candle.superlink.net> > > > > Hi -- > > > > On Tue, 24 Sep 2002, Gavin Sinclair wrote: > > > > > ----- Original Message ----- > > > From: "Yukihiro Matsumoto" <matz / ruby-lang.org> > > > > > > > > > > > |How can I check hash keys and values without case sensitivity? > > > > |Specifically I'm referring to the hash ".has_key?" and ".has_value?" > > > > |methods. I believe these are case sensitive by default. > > > > > > > > Why not simply > > > > > > > > h.key?(k.upcase) > > > > h.value?(v.upcase) > > > > > > > > matz. > > > > > > This has got to be the best solution, as it takes account of the important > fact > > > that noone else has yet mentioned: Hash keys are not necessarily Strings. > > > > What if the key you used is lowercase? like this: > > > > irb(main):002:0> h = {"a" => 1} > > {"a"=>1} > > irb(main):003:0> k = "a" > > "a" > > irb(main):004:0> h.key?(k) > > true > > irb(main):005:0> h.key?(k.upcase) > > false > > > > I think Matz intended that the keys get case-neutralised upon entry into the > hash. Naturally, that stuffs you if you input both "Key" and "kEy" into the > hash, but as someone pointed out, if genuine case-insensitive retrieval is what > you want, then hash is not what you need. > > May I suggest a binary tree or similar structure, in case the original poster > is still interested? > > Gavin this seems to work in all situations (implementation below) : h = Hash.new h.case_numb h['k'] = 'v' puts h.has_key? 'K' -->> false h.ignoring_case do puts h.has_key? 'K' -->> true end this code relies on mapping each case insensive key to it's list of actual keys, and the same for values, eg. h = {'abc' => 'def', 'aBc' => 'dEf'} h.ci_keys = {'ABC' => {'abc' => 'def', 'aBc' => 'dEf'}} h.ci_vals = {'DEF' => {'def' => 'abc', 'dEf' => 'aBc'}} (you could just map everything to true...) implementaion follows - this ones silly, but the idea of tracking information about case insensitivity and allowing the object to 'sometimes' use it is usefull i think... -ara module CIHashMethods attr :ci_keys, true attr :ci_vals, true attr :ci, true def CIHashMethods.extend_object aHash super aHash.ci_keys = Hash.new aHash.ci_vals = Hash.new aHash.ci = false end def []= k, v (self.ci_keys[k.upcase] ||= Hash.new)[k] = v (self.ci_vals[v.upcase] ||= Hash.new)[v] = k super k, v end def has_key? k self.ci and return self.ci_keys.has_key? k.upcase super k end def has_val? v self.ci and return self.ci_vals.has_value? v.upcase super v end def ignoring_case(&block) begin self.ci = true yield block ensure self.ci = false end end end class CIHash < Hash include CIHashMethods end class Hash def case_numb self.extend CIHashMethods end end