"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