2010/2/24 Xavier Noria <fxn / hashref.com>:
> On Wed, Feb 24, 2010 at 11:17 PM, Glenn Ritz <glenn_ritz / yahoo.com> wrote=
:
>> Xavier Noria wrote:
>>> On Wed, Feb 24, 2010 at 10:40 PM, Glenn Ritz <glenn_ritz / yahoo.com>
>>> wrote:
>>>
>>>> I'd like to be able to take a hash whose values are either hashes or
>>>> some other object. If the values are hashes, I'd like to iterate over
>>>> them and keep this up until the values aren't hashes. =A0And I won't k=
now
>>>> how many level there will be until the program is running. =A0Any
>>>> suggestions?
>>>
>>> The iterator should yield... what? key, value pairs when it gets to a
>>> leave? Only values? All pairs no matter the type of the value?
>>
>> If the Hash looks like this:
>>
>> {'en' =3D> {'A' =3D> 1, 'B' =3D> {'C' =3D> 3, 'D' =3D> 'four' }}
>>
>> I'd like to be able to create a new hash that looks like this (it's for
>> a gem that I am trying to write):
>>
>> {'en' =3D> {'A' =3D> Fixnum, 'B' =3D> {'C' =3D> Fixnum, 'D' =3D> String =
}}
>>
>> So I think it should yield the key value pairs when it gets to a leaf,
>> but it also seems like I will need more to be able to create the above
>> hash.
>
> For example
>
> def classify_values(h)
> =A0newh =3D {}
> =A0h.each do |k, v|
> =A0 =A0newh[k] =3D v.is_a?(Hash) ? classify_values(v) : v.class
> =A0end
> =A0newh
> end
>
> p classify_values({'en' =3D> {'A' =3D> 1, 'B' =3D> {'C' =3D> 3, 'D' =3D> =
'four' }}})

I would do it a tad differently:

def classify(o)
  case o
  when Hash
    h =3D {}
    o.each {|k,v| h[k] =3D classify(v)}
    h
  else
    o.class
  end
end

Advantage is that you can stuff anything in the method while your
variant requires the argument to be a Hash.  The difference may seem
subtle but if you add more collection types for special treatment,
you'll will notice a difference in effort to implement it.  I can
simply do

def classify(o)
  case o
  when Hash
    h =3D {}
    o.each {|k,v| h[k] =3D classify(v)}
    h
  when Array
    o.map {|v| classify(v)}
  else
    o.class
  end
end

while you need to do a more complicated code change.

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/